排除派生类对象的方法

时间:2015-02-24 15:13:01

标签: c#

在下面的示例中,我可以添加List类型Animal。由于DogCat来自动物,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 { }

2 个答案:

答案 0 :(得分:2)

致电Test(dogs.Cast<Animal>().ToList())。将参数类型更改为IEnumerable以跳过创建副本的ToList()

intobjectList<Animal>objectList<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>和普通数组。