c# - 将派生类的列表<>转换为基类的列表<>

标签 c# generics

我有两个类:一个基类 (Animal) 和一个派生自 它(Cat)。基类包含一个以 List 作为输入参数的虚方法 Play。像这样

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>());
        }
    }
}

当我编译上面的程序时,出现以下错误

    Error    2    Argument 1: cannot convert from 'System.Collections.Generic.List' to '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 支持已知安全的接口(interface)。 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>将狗添加到实际上是猫列表的内容。

关于c# - 将派生类的列表<>转换为基类的列表<>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3720751/

相关文章:

c# - 在 C# 中禁用和启用按钮

c# - DayOfWeek 获取下一个 DayOfWeek(Monday,Tuesday...Sunday)

c# - 为什么 XSD.EXE 创建两个 .XSD 文件,以及如何使用它们?

java - 使用泛型和动态类类型返回类型转换

generics - 使用类型级计算时类型推断/类型检查失败

c# - 是否可以从 SqlDbType.Xml 类型的输出 SqlParameter 创建 XmlReader?

c# - 没有自动回发的 CheckBox CheckedChanged 事件

java - 未经检查的从通用 T 转换为可比较的阻止编译

c# - 将通用字典转换为不同类型

swift - 创建返回泛型的工厂方法