VB中的通用方法重载编译错误

3

我有一个问题,就是VB.NET编译器无法编译一个类(在一个单独的C#程序集中),该类包含具有泛型参数的两个重载方法。相同程序集中的等效C#代码可以编译而不会出现错误。

这里是这两个方法的签名:

protected void SetValue<T>(T newValue, ref T oldValue)
protected void SetValue<T>(T? newValue, ref T? oldValue) where T : struct

以下是三个演示问题的程序集代码。第一个是C#程序集,其中包含实现泛型方法的基类。第二个是从Base派生的C#类,并正确调用了SetValue的两个重载。第三个是从Base派生的VB类,但无法编译,出现以下错误信息:
错误1:重载决策失败,因为这些参数没有可访问的“SetValue”最具体: “Protected Sub SetValue(Of T As Structure)(newValue As System.Nullable(Of Integer),ByRef oldValue As System.Nullable(Of Integer))”:不是最具体的。 “Protected Sub SetValue(Of T)(newValue As System.Nullable(Of Integer),ByRef oldValue As System.Nullable(Of Integer))”:不是最具体的。
  1. Base Class assembly

    example:

    public class Base
    {
        protected void SetValue<T>(T newValue, ref T oldValue)
        {
        }               
        protected void SetValue<T>(T? newValue, ref T? oldValue) where T : struct
        {
        }
    }
    
  2. C# Derived Class

    example:

    public class DerivedCSharp : Base
    {
        private int _intValue;
        private int? _intNullableValue;    
        public void Test1(int value)
        {
            SetValue(value, ref _intValue);
        }        
        public void Test2(int? value)
        {
            SetValue(value, ref _intNullableValue);
        }
    }
    
  3. VB Derived Class

    example:

    Public Class DerivedVB
        Inherits Base    
        Private _intValue As Integer
        Private _intNullableValue As Nullable(Of Integer)    
        Public Sub Test1(ByVal value As Integer)
            SetValue(value, _intValue)
        End Sub    
        Public Sub Test2(ByVal value As Nullable(Of Integer))
            SetValue(value, _intNullableValue)
        End Sub
    End Class
    

在VB代码中我做错了什么吗?还是说C#和VB在泛型重载解析方面有所不同?如果我将Base方法的参数设为非泛型,则一切都能正确编译,但这样我就必须为每种类型实现SetValue。


你使用的 Visual Studio 和 .Net 版本是什么? - RBarryYoung
我已经在VS2005和VS2010 Beta 1中尝试了这个,结果都是一样的。我认为VS2008也会一样。 - Mike Thompson
这似乎是编译器的一个bug。你应该报告它。 - Konrad Rudolph
Jeff,感谢您恢复我的原始通用代码。 - Mike Thompson
2个回答

2

看起来你需要帮助VB编译器一点,才能选择正确的重载方法进行调用。以下代码对我而言是可编译的:

Public Sub Test1(ByVal value As Integer)
    SetValue(Of Integer)(value, _intValue)
End Sub

Public Sub Test2(ByVal value As Nullable(Of Integer))
    SetValue(Of Integer)(value, _intNullableValue)
End Sub

这样可以避免编译器错误,但是Test2内部的SetValue调用会解析到错误的重载。不错的尝试!当编译正确时,我以为问题已经解决了。 - Mike Thompson
抱歉,我的错。我现在已经编辑了我的回复,使得Test1调用SetValue(T, ref T),而Test2调用SetValue(T?, ref T?)。 - Mattias S

2
我坚持认为这很可能是一个错误。然而,我可以使用Mono VB编译器vbnc复现它。这里有一个(有些混乱的)错误信息,“No non-narrowing (except object)”,我认为这指的是缺少隐式转换,因此是相同的重载解析问题。
问题似乎是编译器的重载解析失败,因为需要一些特殊的管理,这在C#调用中是明确说明的,但在VB调用中没有说明,因为它涉及到ByRef参数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接