一尘不染

将派生类的List <>转换为基类的List <>

c#

我有两个类:一个基类(Animal)和一个从它派生的类(Cat)。基类包含一个虚拟方法Play,该方法将List作为输入参数。

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

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

    错误2参数1:无法从“ System.Collections.Generic.List”转换为“ System.Collections.Generic.List”

反正有做到这一点吗?


阅读 416

收藏
2020-05-19

共1个答案

一尘不染

您无法执行此操作的原因是列表是可写的。假设这是合法的,然后看看出了什么问题:

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支持已知安全的接口。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>将狗添加到实际上是猫名单的东西上。

2020-05-19