遍历 List<interface> 项

Iterating through List<interface> Items

我不明白为什么我不能通过我已经连接的 class 遍历列表。

例如

public interface IAnimal
{
   string Name { get; set; }
}

public class Chicken:IAnimal
{
   public string Name { get; set; }
}

public class Dog:IAnimal
{
   public string Name { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var AnimalList = new List<IAnimal>();

        var Chicken1= new Chicken() { Name = "Chicken" }; 
        var Dog1= new Dog() { Name = "Dog" };

        AnimalList.Add(Dog1);
        AnimalList.Add(Chicken1);

        foreach (Dog obj in AnimalList)
        {
           Console.WriteLine(obj.Name); 
        }
    }
}

我是不是做错了什么,有没有更好的角度来处理这种情况。

每个Dog是一个IAnimal,但不是每个IAnimal是一个Dog。尤其不是 Chicken:它绝对不是 Dog。这就是为什么这个循环在到达 Chicken:

时会 运行 进入异常
foreach (Dog obj in AnimalList) {
    ...
}

但是,如果你这样做

foreach (IAnimal obj in AnimalList) {
    ...
}

或同等学历

foreach (var obj in AnimalList) {
    ...
}

代码将编译并且 运行 正确。

您已定义列表,使其包含 IAnimal.

的元素
var AnimalList = new List<IAnimal>();

然后在循环中将元素指定为 Dog。现在,虽然 Dog 确实实现了 IAnimal,但它并不是唯一实现的类型。因此,如果列表包含 Dog 以外的类型,那么您的循环将失败。

所以你有两种方法来解决这个问题。

一个是你把你的循环改成这样:

foreach (IAnimal obj in AnimalList)
{
    Console.WriteLine(obj.Name); 
}

如果你这样做,你的代码可以正常工作并输出狗和鸡的名字。

但是,如果您只想 return Dog 个实例,您可以过滤列表。你会这样做:

foreach (Dog obj in AnimalList.OfType<Dog>())
{
    Console.WriteLine(obj.Name); 
}

现在只输出狗名