我有两个类:一个基类(Animal)和一个从它派生的类(Cat)。基类包含一个虚拟方法Play,该方法将List作为输入参数。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication9 { class Animal { public virtual void Play(List<Animal> animal) { } } class Cat : Animal { public override void Play(List<Animal> animal) { } } class Program { static void Main(string[] args) { Cat cat = new Cat(); cat.Play(new List<Cat>()); } } }
当我编译上面的程序时,出现以下错误
错误2参数1:无法从“ System.Collections.Generic.List”转换为“ System.Collections.Generic.List”
反正有做到这一点吗?
您无法执行此操作的原因是列表是可写的。假设这是合法的,然后看看出了什么问题:
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>没有任何方法可以写入序列,因此很安全。
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>将狗添加到实际上是猫名单的东西上。
List<Cat>
IEnumerable<Cat>
IEnumerable<Animal>