2010-06-14 59 views
6

下面的代码不编译(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 /双重变体代表可以被分配到彼此,和代表可以通过co/contra-variant方法创建,因此ToString(object)方法可用作Converter<T, string>,因为T始终可保证可转换为object

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

回答

3

这同一个事实,即方差并不适用于价值类型,所以如果限制T喜欢where T : classT得到方差和代码的第一个片段将编译做。

Covariance and Contravariance FAQ:仅当 类型参数是引用类型

方差被支撑。 值 类型不支持差异。

+0

更具体地说,它不适用于无约束的'T',因为它可能是值类型。 – thecoop 2010-06-26 09:28:51

0

第二代码编译因为o导出从object,所以很明显可以调用,它接受一个object任何类型参数的输入的方法。

然而,代表类型是不等于。除非Tobject方法签名不匹配。如果,比如说,Tint,那么您将有一个Converter<int, string>,它与Converter<object, string不一样。他们完全是两个不同类型

您遇到了C#3.0缺乏共同/反对差异的问题。应该在C#更好4.

+0

这是在.NET 4.我更新了我的问题 – thecoop 2010-06-14 11:28:44