2013-10-13 58 views
1

我在想:爲什麼陣列不是逆變?

從C#4.0開始,通用接口允許協變(與通用委託4類似),但泛型類不允許。

陣列支持協方差(S []可轉換爲B []若S子類B)

因此,它是完全有效的做到這一點:

string[] obj = new string[3]; 
     obj[0]="1"; 
     obj[1]="2"; 
     obj[2]="3"; 

Do something with : (obj as object[]) 
Do something with : (object[])obj ... 
Do something with : ((IEnumerable<object>)obj) 

這種可重用性的缺點是元素分配可能在運行時失敗

(obj as object[])[0] = new DateTime(); //errrr... 

好的 - 它可能會失敗。

所以如果在運行時它已經失效了(這是由我來檢查它),爲什麼他們不把它也作爲contravariant

 object[] obj = new object[3]; 
     obj[0]="1"; 
     obj[1]="2"; 
     obj[2]="3"; 

這樣我就能做到(我的責任):

(obj as string[])... 
+0

所以你想能夠寫'(字符串[])(object [])new Button [5]'? – SLaks

+0

@SLaks我們知道這裏有一個問題(運行時)。我只是說,如果它是由我來檢查類型 - 爲什麼他們沒有使它也是逆變的,以便我能夠使用它從另一種方式。 –

+1

這不是C#1.0只是複製Java所做的事情嗎? – dtb

回答

3

這已經夠糟糕,他們讓協方差,因爲那時每次你寫一個數組,即設置一個其元素添加到新的參考中,則必須執行類型檢查。

如果它們也允許反轉,那麼數組中的每個讀取也需要類型檢查。那會更糟。

在過去的.NET陣列經常通過的地方,預計接收器只能從讀取陣列。那麼「瘋狂」的協變有點意義。逆變並沒有那麼有用。