铸造名单&LT;&GT;的派生类清单及LT;&GT;基类的 [英] Casting List<> of Derived class to List<> of base class
问题描述
我有两个类:一个基类(动物)和一个类从派生
它(CAT).Base类包含一个虚方法是播放列表需要输入parameter.Something这样
I have two classes: a base class (Animal) and a class deriving from it (Cat).Base class contains one virtual method Play that takes List as input parameter.Something like this
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>());
}
}
}
当我编译上面的程序,我收到以下错误
When i compile the above program,i get the following error
Error 2 Argument 1: cannot convert from 'System.Collections.Generic.List' to 'System.Collections.Generic.List'
反正有没有做到这一点?
Is there anyway to accomplish this?
推荐答案
您不能这样做的原因是因为一个列表是可写的。假设它是合法的,看看有什么不顺心:
The reason you cannot do this is because a list is writable. Suppose it were legal, and see what goes wrong:
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!
好狗猫我,这是不良。
Well dog my cats, that is badness.
要该功能被称为通用协方差,它在C#4被支撑为已知是安全的接口。 的IEnumerable&LT; T&GT;
没有任何办法写序,因此它是安全的。
The feature you want is called "generic covariance" and it is supported in C# 4 for interfaces that are known to be safe. IEnumerable<T>
does not have any way to write to the sequence, so it is safe.
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,因为列表&LT;猫&GT;
可转换为的IEnumerable&LT;猫&GT;
,这是转换为的IEnumerable&LT;动物&GT;
。有没有办法玩可以用的IEnumerable&LT;动物方式&gt;
来狗添加的东西,实际上是猫的列表
That will work in C# 4 because List<Cat>
is convertible to IEnumerable<Cat>
, which is convertible to IEnumerable<Animal>
. There is no way that Play can use IEnumerable<Animal>
to add a dog to something that is actually a list of cats.
这篇关于铸造名单&LT;&GT;的派生类清单及LT;&GT;基类的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!