0
爲什麼List<T>
不上T
協變的原因,而IEnumerable<T>
是協對T
往往是由這樣一個例子來說明。通用協方差編譯時安全檢查
考慮以下類:
public class Fruit
{
}
public class Apple : Fruit
{
}
public class Banana : Fruit
{
}
允許以下:
public void Permitted()
{
IEnumerable<Fruit> bananas = new List<Banana>
{
new Banana(),
new Banana(),
new Banana(),
};
foreach (Fruit banana in bananas)
{
// This is all good, because a banana "is a" fruit and
// we can treat it as such.
}
}
是不允許以下:
public void Disallowed()
{
// Compiler rejects this!
List<Fruit> bananas = new List<Banana>
{
new Banana(),
new Banana(),
new Banana(),
};
// ...Otherwise we can add an apple to a list containing bananas
bananas.Add(new Apple());
}
但是,我們仍然可以通過執行實現這一目標如下:
public void Loophole()
{
// Compiler is happy again
IEnumerable<Fruit> bananas = new List<Banana>
{
new Banana(),
new Banana(),
new Banana(),
};
// ...And now we can add an apple to a list of bananas
bananas.ToList().Add(new Apple());
}
當然,我們可以做這樣的:
public void AlsoAllowed()
{
var fruit = new List<Fruit>();
fruit.Add(new Apple());
fruit.Add(new Banana());
}
爲List<T>
不是協變的普遍的說法(按照我的理解)是,這樣做將使我們能夠任意基本對象添加到包含派生對象的集合。也許這是一種過度簡單化,但是這不是說上面的例子在做什麼?
只是爲了補充一點,在第二個例子中,將'Apple'和'Banana'添加到'fruit'絕對沒有任何問題,它不僅被輸入爲'List',而且被實例化。 –
現在很明顯,你提到它 - 謝謝! – LeopardSkinPillBoxHat