2010-06-14 88 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