我遇到了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
以下是演示此问题的三个程序集的代码。第一个是带有Base类的C#程序集,它实现了泛型方法。第二个是从Base派生的C#类,并正确调用SetValue的两个重载。第三个是从Base派生的VB类,但无法使用以下错误消息进行编译:
错误1重载解析失败,因为没有可访问的“SetValue”对这些参数最具体: '受保护的子SetValue(T作为结构)(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))':不是最具体的。
基类组装
示例:
public class Base
{
protected void SetValue<T>(T newValue, ref T oldValue)
{
}
protected void SetValue<T>(T? newValue, ref T? oldValue) where T : struct
{
}
}
C#派生类
示例:
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);
}
}
VB派生类
示例:
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#&amp; VB在通用重载解析方面有何不同?如果我在Base非泛型中创建方法参数,那么一切都正确编译,但是我必须为我希望支持的每种类型实现SetValue。
答案 0 :(得分: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
答案 1 :(得分:2)
我支持我的评论,这很可能是一个错误。但是,我可以使用Mono VB编译器vbnc
重现它。这里的(有点损坏的)错误消息是“No non-narrowing(除了object)” - 我认为它指的是缺少隐式转换,因此导致相同的重载解析问题。
问题似乎是编译器的重载解析因为ByRef
参数而失败,因为这需要一些特殊的管理,这在C#调用中是明确的,而不是在VB调用中。