【问题标题】:How is method group overload resolution different to method call overload resolution?方法组重载解析与方法调用重载解析有何不同?
【发布时间】:2010-06-14 11:10:21
【问题描述】:

以下代码无法编译 (error CS0123: No overload for 'System.Convert.ToString(object)' matches delegate 'System.Converter<T,string>'):

class A<T> {
    void Method(T obj) {
        Converter<T, string> toString = Convert.ToString;

        // this doesn't work either (on .NET 4):
        Converter<object, string> toString2 = Convert.ToString;
        Converter<T, string> toString3 = toString2;            
    }
}

但是,这样做:

class A<T> {
    void Method(T obj) {
        // o is a T, and Convert.ToString(o) is using
        // string Convert.ToString(object o)

        Converter<T, string> toString = o => Convert.ToString(o);
    }
}

在c#4中,co/contra-variant delegate可以相互赋值,并且可以从co/contra-variant方法创建delegate,所以ToString(object)方法可以作为Converter&lt;T, string&gt;,作为@ 987654326@ 始终保证可转换为object

因此,第一个示例(方法组重载解析)应该是找到唯一适用的方法string Convert.ToString(object o),与方法调用重载解析相同。为什么方法组和方法调用重载解析会产生不同的结果?

【问题讨论】:

    标签: c# .net-4.0 covariance overloading


    【解决方案1】:

    这与方差不适用于值类型这一事实有关,因此如果您像 where T : class 一样限制 T,您会在 T 上获得方差,并且代码的第一个 sn-p 将编译。

    来自Covariance and Contravariance FAQ

    仅当类型 参数是引用类型。 值不支持方差 类型。

    【讨论】:

    • 更具体地说,它不适用于不受约束的T,因为它可能是一个值类型。
    【解决方案2】:

    第二个代码编译是因为o 派生来自object,所以显然你可以调用一个方法,该方法将object作为any类型的输入参数。

    但是,委托类型不相等。除非Tobject,否则方法签名不匹配。例如,如果Tint,那么您将拥有一个与Converter&lt;object, string 不同的Converter&lt;int, string&gt;。它们是两种完全不同的类型

    您遇到了 C# 3.0 缺乏协方差的问题。在 C# 4 中应该会更好。

    【讨论】:

      猜你喜欢
      • 2020-05-08
      • 1970-01-01
      • 2019-09-17
      • 1970-01-01
      • 2011-10-11
      • 2011-04-10
      • 2021-11-12
      相关资源
      最近更新 更多