我发现 C# 和 VB 编译器之间的重载解析存在差异。我不确定这是错误还是设计使然:
Public Class Class1
Public Sub ThisBreaks()
' These work '
Foo(Of String)(Function() String.Empty) 'Expression overload '
Foo(String.Empty) 'T overload '
' This breaks '
Foo(Function() String.Empty)
End Sub
Public Sub Foo(Of T)(ByVal value As T)
End Sub
Public Sub Foo(Of T)(ByVal expression As Expression(Of Func(Of T)))
End Sub
End Class
请注意,重载的 Foo 方法是否在 VB 中定义并不重要。唯一重要的是调用点是在 VB 中。
VB编译器会报错:
重载解析失败,因为没有可访问的“Foo”对于这些参数来说是最具体的:
'Public Sub Foo(Of String)(expression As System.Linq.Expressions.Expression(Of System.Func(Of String)))':不是最具体。
'Public Sub Foo(Of )(value As )':不是最具体的。
添加用于比较的 C# 代码:
class Class1
{
public void ThisDoesntBreakInCSharp()
{
Foo<string>(() => string.Empty);
Foo(string.Empty);
Foo(() => string.Empty);
}
public void Foo<T>(T value)
{
}
public void Foo<T>(Expression<Func<T>> expression)
{
}
}
暂时忽略“如果 C# 编译器这样做,它一定是正确的,因此它是 VB 编译器中的一个错误”的假设。我立刻就能看出其中的歧义:
Foo(Function() String.Empty)
可以调用T
版本,替换Func(Of String)
或者它可以将单行 lambda 重新分类到表达式树中,并调用Expression(Of Func(Of String))
方法。没有理由优先选择其中之一,事实上 VB 会阻止您继续操作,而不强迫您指定所需的哪一个。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)