Причина, по которой вы не можете этого сделать, заключается в том, что список доступен для записи.Предположим, это было законно, и посмотрим, что пошло не так:
List<Cat> cats = new List<Cat>();
List<Animal> animals = cats; // Trouble brewing...
animals.Add(new Dog()); // hey, we just added a dog to a list of cats...
cats[0].Speak(); // Woof!
Хорошо, собаку мои кошки, это плохо.
Требуемая функция называется «универсальная ковариация» и поддерживается в C # 4 для интерфейсов, о которых известно, что они безопасны.IEnumerable<T>
не имеет никакого способа записи в последовательность, поэтому это безопасно.
class Animal
{
public virtual void Play(IEnumerable<Animal> animals) { }
}
class Cat : Animal
{
public override void Play(IEnumerable<Animal> animals) { }
}
class Program
{
static void Main()
{
Cat cat = new Cat();
cat.Play(new List<Cat>());
}
}
Это будет работать в C # 4, потому что List<Cat>
конвертируется в IEnumerable<Cat>
, который конвертируется в IEnumerable<Animal>
.Play не может использовать IEnumerable<Animal>
, чтобы добавить собаку к чему-то, что фактически является списком кошек.