2010-07-26 63 views
5

在通過C#第三版CLR CLR有,我似乎無法弄懂一個例子:禁忌和Co-方差 - 通過C#

不變意味着該通用 類型參數不能改變。在本章中,我已經示出了 只有不變的通用類型 參數。 n

反義含義通用 類型參數可以從類 更改爲從它派生的類。在C#中,你 表明逆變泛型類型 參數與在關鍵字

反變換泛型類型參數 只能出現在輸入位置 ,如方法的參數。 n 協變意味着通用 類型參數可以從類 更改爲其基類之一。在C#中,你的 表示covariant泛型類型 參數out關鍵字。 協變泛型類型參數 只能在輸出位置出現,例如 作爲方法的返回類型。

作者然後進到舉這個例子:

public delegate TResult Func<in T, out TResult>(T arg); 

在此,一般類型參數T被標有在關鍵詞 ,使它 逆變;和通用 類型參數TResult標有 出關鍵字,使其協變

這裏就是我碰上下頁(292)上的問題,那麼他那張說,相反使用時接口。

當使用採取通用的參數和返回值的代表,建議 始終指定逆變和協方差的in和out關鍵字時>可能, 因爲這樣做有沒有不良影響,使您的委託用於更多場景。 像代表一樣,具有泛型類型參數的接口可以使其類型參數爲 逆變或協變。下面是一個接口與一個逆變示例>泛型 類型參數:

public interface IEnumerator<out T> : IEnumerator { 
Boolean MoveNext(); 
T Current { get; } 
} 

因爲T是逆變的,所以能夠有以下代碼編譯和運行>成功:

// This method accepts an IEnumerable of any reference type 
Int32 Count(IEnumerable<Object> collection) { ... } 
... 
// The call below passes an IEnumerable<String> to Count 
Int32 c = Count(new[] { "Grant" }); 

在第二個示例中,他使用out關鍵字(IEnumerator<out T>),然後將其稱爲逆變換。這是正確的還是我錯過了一些東西。在界面中定義協變變換是否有區別? I have been to Oreilly's website regarding this book and this is not listed.

+0

重要的是要注意'Delegate.Combine'的設計從根本上與方差不兼容。如果一個例行程序的委託類型的初空場行動'',並嘗試向'Combine'它與'行動',類型的字段'行動'將舉行一個參考的作用'' 。如果一個人試圖'結合'與'行動',則嘗試失敗。出於這個原因,可能曾經與'Combine'一起使用的代表類型不應該是協變或逆變。這太糟糕了委託類型沒有定義自己的'Combine'方法,因爲... – supercat 2012-10-19 19:20:26

+0

...的方法'行動 .Combine'可能安全地採取行動''並將其轉化爲一種'行動 ',知道這種轉換的結果只能被代碼所使用,代碼會給它一個'Cat'。 – supercat 2012-10-19 19:22:52

回答

20

out = 協變in = 逆變

任意一個關鍵詞到對面的是我的書的錯誤,我將在以後的版本糾正。

+6

哇 - 歡迎SO,傑弗裏! – 2010-07-26 14:14:55

+8

你知道你剛剛進入開發者版的加利福尼亞酒店,對嗎? – 2010-07-26 14:41:40

+0

冰上的粉紅色香檳,有人嗎? – 2010-07-26 15:37:28

8

這是一個錯誤。這絕對是一個協變的例子。代表和接口之間的協變和逆變意義沒有區別。

我向您建議奧賴利報告錯誤。

+1

或作者會來直接回答...':)' – jjnguy 2010-07-26 14:21:57

+1

@Justin:嗯,是的,這始終是一個選擇;) – 2010-07-26 14:28:31