C# 4.0 中的泛型變體
C# 4.0 中的 Generic Variance 的實現方式使得可以毫無例外地編寫以下內容(這在 C# 3.0 中會發生):
List<int> intList = new List<int>(); List<object> objectList = intList;[範例非功能性:參見 Jon Skeet 的回答]
我最近參加了一個會議,Jon Skeet 對通用變異數進行了出色的概述,但我不確定我是否完全理解它 - 我理解
in和out關鍵字在反變異數和共變異數方面的重要性,但我很好奇幕後發生的事情。**執行此程式碼時,CLR 會看到什麼?**它是隱式轉換
List<int>為List<object>還是簡單地內置,我們現在可以在派生類型之間轉換為父類型?出於興趣,為什麼在以前的版本中沒有引入它,主要的好處是什麼 - 即現實世界的使用?
有關通用差異的這篇文章的更多資訊(但問題非常過時,正在尋找真實的最新資訊)
不,您的範例不起作用,原因有以下三個:
- 類(例如
List<T>)是不變的;只有委託和介面是變體- 為了使變異數起作用,介面只能在一個方向上使用類型參數(in 表示逆變,out 表示協變)
- 不支持值類型作為變數的類型參數 -例如,沒有從
IEnumerable<int>到的轉換IEnumerable<object>(程式碼在 C# 3.0 和 4.0 中都無法編譯 - 也不例外。)
所以這會起作用:
IEnumerable<string> strings = new List<string>(); IEnumerable<object> objects = strings;CLR 只使用未更改的引用 - 沒有創建新對象。所以,如果你打電話
objects.GetType(),你仍然會得到List<string>.我相信它沒有更早地引入,因為語言設計者仍然必須制定如何公開它的細節——它從 v2.1 開始就在 CLR 中。
好處與您希望能夠將一種類型用作另一種類型的其他時間相同。使用我上週六使用的相同範例,如果您有一些工具
IComparer<Shape>可以按區域比較形狀,那麼您不能使用它來對 a 進行排序真是太瘋狂了List<Circle>- 如果它可以比較任何兩個形狀,它當然可以比較任何兩個界。從 C# 4 開始,將有一個從IComparer<Shape>to的逆變轉換,IComparer<Circle>因此您可以呼叫circles.Sort(areaComparer).