Проще говоря, IList<T>
не является ковариантным, тогда как IEnumerable<T>
есть. И вот почему ...
Предположим, IList<T>
было ковариантным. Приведенный ниже код явно не является типобезопасным ... но где бы вы хотели, чтобы ошибка была?
IList<Apple> apples = new List<Apple>();
IList<Fruit> fruitBasket = apples;
fruitBasket.Add(new Banana()); // Aargh! Added a Banana to a bunch of Apples!
Apple apple = apples[0]; // This should be okay, but wouldn't be
Для лотов подробностей по дисперсии, см. серию постов Эрика Липперта в блоге или посмотрите видео моего разговора об отклонениях от NDC. 1017 *
По сути, дисперсия допускается только в тех случаях, когда она гарантированно безопасна (и с сохранением представления, поэтому вы не можете преобразовать IEnumerable<int>
в IEnumerable<object>
- преобразование в бокс не сохраняет представление) .