不變性
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!
通過省略 in
和 out
關鍵字來宣告不變型別引數。
interface IList<T> { /* ... */ }