不变性

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> { /* ... */ }