我有圓的物體(如圈實現IShape接口的數組和我有了的List<IShape>
參數的函數。爲什麼我不能在我的圈子到此的數組傳遞?爲什麼.Net 4不允許我傳入一個接口數組?
視覺工作室給我生成錯誤的說法不能轉換List<Circle>
到List<IShape>
我有圓的物體(如圈實現IShape接口的數組和我有了的List<IShape>
參數的函數。爲什麼我不能在我的圈子到此的數組傳遞?爲什麼.Net 4不允許我傳入一個接口數組?
視覺工作室給我生成錯誤的說法不能轉換List<Circle>
到List<IShape>
簡短的回答是,因爲功能Foo
可以實現這樣的:
void Foo(IList<IShape> c)
{
c.Add(new Square());
}
如果你通過了List<Circle>
到Foo
,所提供的類型將不能存儲Square
,即使類型簽名聲稱它沒問題。 IList<T>
不是covariant:一般IList<Circle>
不能是IList<IShape>
,因爲它不支持添加任意形狀。
修復方法是使用IEnumerable<IShape>
來接受Foo
中的參數,但這在所有情況下都不起作用。 IEnumerable<T>
是協變:專門的IEnumerable<Circle>
符合一般IEnumerable<IShape>
的合同。
這種行爲也是一件好事。當它不應該是協變時,一個經典的例子是一個數組。下面的代碼可以編譯,但會在運行時失敗:
void Bar()
{
// legal in C#:
object[] o = new string[10];
// fails with ArrayTypeMismatchException: can't store Int in a String[]
o[0] = 10;
}
實際上,'IEnumerable
@ FrancisR.Griffiths-Keam,你錯了。從.NET 4開始,IEnumerable
@AnthonyPegram Ahh我錯過了那個備忘錄,謝謝你的記錄。 – 2013-03-22 04:10:54
你的意思是你有一個列表''和功能'美孚(名單 C)'和'圈:IShape'?考慮'Foo'是否有'c.Add(new Square())'這一行。 –
2013-03-22 02:44:25
這是一個經常被問到的問題。搜索包含可枚舉類型的協方差的問題。 – 2013-03-22 02:44:49
請問IEnumerable夠用嗎?並非所有類型都是協變的。 –
2013-03-22 02:45:21