13

此代碼:爲什麼Resharper說:「使用此代碼,從字符串[]到對象[]的共變數組轉換可能導致寫操作中的運行時異常?

comboBoxMonth.Items.AddRange(UsageRptConstsAndUtils.months.ToArray()); 

public static List<String> months = new List<String> 
{ 
    "Jan", 
    "Feb", 
    "Mar", 
    "Apr", 
    "May", 
    "Jun", 
    "Jul", 
    "Aug", 
    "Sep", 
    "Oct", 
    "Nov", 
    "Dec" 
}; 

打開R·守財奴樣該投訴,「從字符串[]共變量數組轉換爲一個對象[]可引起上寫入操作的運行時異常」。

實際上,此代碼完美工作 - 組合框填充月份值; Resharper關於什麼,我能做些什麼來減輕它的疑慮?

如果僅僅是泛型列表可能包含錯誤的數據,我不會擔心 - 如果遇到任何問題,就很容易找到問題。

+2

我想一個解決方法是使用'List '而不是'List '。 –

回答

21

方法comboBoxMonth.Items.AddRange預計object[]參數。 months.ToArray()string[]。從string[]object[]的強制轉換是有效的,但如果該方法試圖修改該數組的元素,則會出現運行時錯誤。在這種情況下,它不會,所以你可以忽略警告。

如果惹惱了你,你可以使用ToArray<object>()

comboBoxMonth.Items.AddRange(UsageRptConstsAndUtils.months.ToArray<object>()); 

它將返回object[]沒有投將需要。

+1

如果一個方法試圖修改數組的元素*,你的意思是什麼?修改已經在數組中的元素應該不成問題。 –

+2

@YuvalItzchakov:如果該方法嘗試將一個香蕉分配給一個真正爲字符串數組的對象數組中的一個元素,那麼在運行時將會失敗。人們合理地期望將香蕉分配到一組物體中將會成功,但它可能不會。 –

+0

@EricLippert是的,我明白了,這就是我在答案中所表達的意思。但是我認爲這句話中含糊不清,指出修改現有元素會導致運行時異常 –

13

爲例來說明這個問題:

void Main() 
{ 
    Animal[] animals = new Girafee[2]; 
    animals[0] = new Zebra(); 
} 

public class Animal { } 
public class Girafee : Animal { } 
public class Zebra : Animal { } 

這將在運行時拋出ArrayTypeMismatchException

R#基本上暗示了一個可能的問題,即您將string[]指定給object[],這完全是編譯器允許的,但如果有一個對象,它可能會導致運行時異常共享相同的基類,分配給已經指向不同類型的數組(在我的例子中,我們實際上指向了girafee數組)。數組協方差的意思是,它不能爲您提供與泛型相關的編譯時安全性。

這個埃裏克利珀會談Covariance and Contravariance in C#, Part Two: Array Covariance

不幸的是,這種特殊的協方差被打破。因爲Java需要它,並且CLR設計人員希望 能夠支持Java類語言,所以它被添加到CLR中爲 。然後,我們將它添加到C#中的 ,因爲它在CLR中。這個決定在 這個時候頗有爭議,我對此並不滿意,但是我們現在沒有什麼可以做的 。

這是爲什麼破裂?因爲將一隻海龜 放入一組動物應該總是合法的。使用語言中的數組協方差和 運行時間,您不能保證動物數組可以接受 海龜,因爲後備存儲實際上可能是一組 長頸鹿。

相關問題