这是在VB.NET编译器或设计错误?这是、编译器、错误、NET

2023-09-03 05:48:06 作者:梦想不只是梦和想

我发现在C#和VB的编译器的重载的差异。我不知道这是否是一个错误或设计的:

 公共类的Class1
    公用Sub ThisBreaks()

        这些工作
        美孚(串)(函数()的String.Empty)防爆pression超载
        美孚(的String.Empty)'T超载

        这打破了
        美孚(功能()的String.Empty)
    结束小组

    公用Sub美孚(Of T)中(BYVAL值作为T)

    结束小组

    公用Sub美孚(Of T)中(BYVAL EX pression为Ex pression(中Func键中(T)))

    结束小组
末级
 

请注意,如果重载富-方法在VB或没有被定义也没关系。唯一重要的事情是调用的位置是在VB。

在VB编译器会报告错误:

  

重载决策失败,因为没有可访问的'富'是最具体的对于这些参数:

公用Sub富(串)(EX pression作为System.Linq.Ex pressions.Ex pression(中System.Func中(字符串))):不最具体的。的

公用Sub美孚(中)(值)':不是最具体的的

添加C#code的工作进行比较:

 类1级
{
    公共无效ThisDoesntBreakInCSharp()
    {
        美孚<字符串>(()=>的String.Empty);
        美孚(的String.Empty);
        美孚(()=>的String.Empty);
    }

    公共无效美孚< T>(吨价)
    {

    }

    公共无效美孚< T>(出pression< Func键< T>>除权pression)
    {

    }
}
 

解决方案

我是pretty的肯定,我已经找到了原因,这是不是VB编译器的短来,但它是一个短即将到来的C#编译器。

考虑哪些是合法的,在VB中的以下内容:

 暗淡富=()的函数的String.Empty
 
vb.net问题,求代码

等效不会是合法的,在C#中:

 变种富=()=>的String.Empty;
 

所以,类型推断是因为这在上例中参数的VB强一点,函数()的String.Empty 可以推断为功能这将是适用于美孚(Of T)中(BYVAL值作为T)(串)过载。

在C#中这不可能,因为发生在()=>的String.Empty 永远不能被未经上下文推导出,因此可以推断,在离pression超负荷而不是在T-过载

I've found a difference in overload resolution between the C# and the VB-compiler. I'm not sure if it's an error or by design:

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

Note that it doesn't matter if the overloaded Foo-methods are defined in VB or not. The only thing that matters is that the call site is in VB.

The VB-compiler will report an error:

Overload resolution failed because no accessible 'Foo' is most specific for these arguments:

'Public Sub Foo(Of String)(expression As System.Linq.Expressions.Expression(Of System.Func(Of String)))': Not most specific.

'Public Sub Foo(Of )(value As )': Not most specific.

Adding the C# code which works for comparison:

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)
    {

    }
}

解决方案

I'm pretty sure I've found the reason for this and it is not a short coming of the VB-compiler but it is a short coming of the C# compiler.

Consider the following which is legal in VB:

Dim foo = Function() String.Empty

The equivalent would not be legal in c#:

var foo = () => string.Empty;

So, type inference is a bit stronger in VB, because of this the argument in the example Function() String.Empty can be inferred to Function(Of String) which would be applicable to the Foo(Of T)(ByVal value As T) overload.

In C# this can not happen since the () => string.Empty can never be inferred without context, it can be inferred in the expression overload but not in the T-overload.