方法组重载决策与方法调用重载决策有何不同?

时间:2010-06-14 11:10:22

标签: c# .net-4.0 covariance overloading

以下代码无法编译(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代表分配给彼此,并且可以使用co / contra-variant方法创建代理,因此ToString(object)方法可以用作Converter<T, string> },因为T始终保证可以转换为object

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

2 个答案:

答案 0 :(得分:3)

这与方差不适用于值类型这一事实有关,因此,如果您限制T where T : class T,您会在{{1}}上获得差异,并且第一段代码将会编译。

来自Covariance and Contravariance FAQ

  

仅在类型时支持差异   参数是引用类型。   值不支持差异   类型。

答案 1 :(得分:0)

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

但是,委托类型不等于。除非Tobject,否则方法签名不匹配。例如,如果Tint,则您的Converter<int, string>Converter<object, string不同。它们是两种完全不同类型

你正在解决围绕C#3.0缺乏共同/反差的问题。在C#4中应该更好。