不變性

IList<T> 永遠不是不同的 IList<T1> 的子型別。IList 在其型別引數中是不變的

class Animal { /* ... */ }
class Dog : Animal { /* ... */ }

IList<Dog> dogs = new List<Dog>();
IList<Animal> animals = dogs;  // type error

列表沒有子型別關係,因為你可以將值放入列表中從列表中取值。

如果 IList 是協變的,你將能夠將錯誤子型別的項新增到給定列表中。

IList<Animal> animals = new List<Dog>();  // supposing this were allowed...
animals.Add(new Giraffe());  // ... then this would also be allowed, which is bad!

如果 IList 是逆變的,你將能夠從給定列表中提取錯誤子型別的值。

IList<Dog> dogs = new List<Animal> { new Dog(), new Giraffe() };  // if this were allowed...
Dog dog = dogs[1];  // ... then this would be allowed, which is bad!

通過省略 inout 關鍵字來宣告不變型別引數。

interface IList<T> { /* ... */ }