Здесь есть пара вопросов.
Сначала: «Я могу назначить объект типа Tiger переменной типа Animal. Почему я не могу назначить объект типа List Tiger переменной типа List of Animal?»
Потому что тогда это происходит:
List<Tiger> tigers = new List<Tiger>();
List<Animal> animals = tigers; // this is illegal because if we allow it...
animals.Add(new Giraffe()); // ... then you just put a giraffe into a list of tigers.
В C # 4 это будет законно:
IEnumerable<Tiger> tigers = new List<Tiger>();
IEnumerable<Animal> animals = tigers;
Это допустимо, потому что IEnumerable<T>
не имеет метода "Добавить", и поэтому это гарантированно безопасно.
См. Мою серию статей о ковариации для получения подробной информации об этой новой функции C # 4.
http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx
Второй вопрос: «Как я мог инициализировать новый экземпляр Тигра от определенного Животного?»
Вы не можете. Это животное может быть Божья коровка. Как вы собираетесь инициализировать нового тигра из экземпляра Божья коровка? Это не имеет никакого смысла, поэтому мы не позволяем вам сделать это. Если вы хотите написать свой собственный специальный метод, который знает, как превратить произвольных животных в тигров, вы можете это сделать. Но мы не знаем, как это сделать для вас.