我很難理解爲什麼C#中的數組是協變的,並且這個協方差可以帶來什麼好處。考慮以下瑣碎的代碼示例:爲什麼C#數組是協變的,它帶來了什麼好處?
object[] myArray = new string[1];
myArray[0] = 1;
該代碼將編譯好的,但會毫不客氣地也許並不奇怪,在運行時發生爆炸。
如果我試圖嘗試使用泛型的相同的東西,編譯器會抱怨我,我會在早期階段意識到我的愚蠢,所以我的問題是這樣的:爲什麼C#編譯器允許與數組的協方差,潛在的好處是什麼?
我很難理解爲什麼C#中的數組是協變的,並且這個協方差可以帶來什麼好處。考慮以下瑣碎的代碼示例:爲什麼C#數組是協變的,它帶來了什麼好處?
object[] myArray = new string[1];
myArray[0] = 1;
該代碼將編譯好的,但會毫不客氣地也許並不奇怪,在運行時發生爆炸。
如果我試圖嘗試使用泛型的相同的東西,編譯器會抱怨我,我會在早期階段意識到我的愚蠢,所以我的問題是這樣的:爲什麼C#編譯器允許與數組的協方差,潛在的好處是什麼?
U不幸的是,這種特殊的協變性被打破了。它被添加到CLR是因爲Java需要它,而CLR設計者希望能夠支持類似Java的語言。然後,我們將它添加到C#中,因爲它在CLR中。這個決定當時頗具爭議,我對此並不滿意,但現在我們無能爲力。
在許多情況下,代碼將在陣列的插槽之間移動或複製項目。假設Arr
是一個具有至少兩個元素的一維數組,則無論Arr
或其中包含的元素的類型如何,以下代碼都可以工作。
Object temp = Arr[1];
Arr[1] = Arr[0];
Arr[0] = temp;
此代碼將是低效的,如果Arr
爲值類型,但由於temp
被讀出的陣列中,陣列的類型是保證能夠保持這樣的值。代碼將不得不boxbox和unbox value-type元素,因此對於這些類型來說效率很低,但它無論如何都會起作用。
請注意,雖然使數組協變是允許排序方法在任意數組類型上工作的一種方法,但它不是唯一的方法。另一種方法是讓System.Array
包含一些方法和屬性,它們的參數與底層元素類型無關。例如,它可能包括一些簡單的方法,如Swap
,CopyItem
和Roll
,以及可能的方法來執行更復雜的排列給定的索引列表。請注意,與上面顯示的代碼不同,像Int[]
這樣的類型可以以避免裝箱和取消裝箱的方式覆蓋其Swap
方法。
mquander贏得引用博客而不是僅僅鏈接到它。 – 2010-08-18 21:00:46
@Jon B - 並引用_relevant_位。 – Oded 2010-08-18 21:02:01
感謝您獲取更多信息的鏈接。很有用。 – nukefusion 2010-08-19 15:41:22