在下面的示例中,我可以添加List
类型Animal
。由于Dog
和Cat
来自动物,List
可以包含每个动物。但是,如果我有一个接受List<Animal>
的方法,则无法传入引用List<Dog>
。如果Dog
来自动物,为什么这不起作用?但是,如果我有一个方法除了Object
类型的参数,并且所有对象都来自Object
,它就可以工作。
class Program
{
static void Main(string[] args)
{
List<Animal> animals = new List<Animal>();
animals.Add(new Dog() { Color = "Black" }); // allowed since Dog derives from Animal
List<Dog> dogs = new List<Dog>();
dogs.Add(new Dog() { Color = "White" });
Test(animals);
Test(dogs); // not allowed - does not compile
Test2(dogs); // valid as all objects derive from object
}
static void Test(List<Animal> animals) {
// do something
}
static void Test2(object obj) {
}
}
public class Animal {
public String Color { get; set; }
}
public class Dog : Animal { }
public class Cat : Animal { }
答案 0 :(得分:2)
致电Test(dogs.Cast<Animal>().ToList())
。将参数类型更改为IEnumerable以跳过创建副本的ToList()
。
int
是object
。 List<Animal>
是object
,List<Dog>
也是List<Dog>
。但List<Animal>
不是{{1}}。
答案 1 :(得分:2)
想象一下Test(dogs)
做了编译。然后想象Test()
的实现如下:
static void Test(List<Animal> animals)
{
animals.Add(new Cat()); // Where Cat is derived from Animal
}
你刚刚在狗的名单中添加了一只猫......显然,这是不允许的。这就是为什么它没有。
但是,如果您只访问列表中的元素而不是添加到列表中,则可以像这样声明Test()
:
static void Test(IEnumerable<Animal> animals)
{
foreach (var animal in animals)
{
// Do something with animal.
}
}
然后你可以传递任何实现IEnumerable<T>
的集合类型,例如List<T>
和普通数组。