演员表<>派生类的列表<>基类的 [英] Casting List<> of Derived class to List<> of base class

查看:22
本文介绍了演员表<>派生类的列表<>基类的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个类:一个基类(Animal)和一个派生自的类it (Cat).Base 类包含一个虚方法 Play,它将 List 作为输入参数.类似这样

使用系统;使用 System.Collections.Generic;使用 System.Linq;使用 System.Text;命名空间 ConsoleApplication9{类动物{公共虚拟无效播放(列表<动物>动物){}}猫类:动物{公共覆盖无效播放(列表<动物>动物){}}课程计划{静态无效主(字符串 [] args){Cat cat = new Cat();cat.Play(new List());}}}

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

<前>错误 2 参数 1:无法从System.Collections.Generic.List"转换为System.Collections.Generic.List"

有没有办法做到这一点?

解决方案

你不能这样做的原因是因为列表是可写的.假设它是合法的,看看哪里出了问题:

List猫 = 新列表<猫>();列表<动物>动物 = 猫;//问题正在酝酿中...动物.添加(新狗());//嘿,我们刚刚在猫列表中添加了一条狗...猫 [0].Speak();//哇!

好吧,我的猫,那太糟糕了.

您想要的功能称为通用协方差",C# 4 支持已知安全的接口.IEnumerable 没有办法写入序列,所以是安全的.

类动物{public virtual void Play(IEnumerable动物){}}猫类:动物{公共覆盖无效播放(IEnumerable动物){}}课程计划{静态无效主(){Cat cat = new Cat();cat.Play(new List());}}

这将适用于 C# 4,因为 List 可转换为 IEnumerable,后者可转换为 IEnumerable>.Play 无法使用 IEnumerable 将狗添加到实际上是猫的列表中.

I have two classes: a base class (Animal) and a class deriving from it (Cat).Base class contains one virtual method Play that takes List as input parameter.Something like this

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

When i compile the above program,i get the following error

    Error    2    Argument 1: cannot convert from 'System.Collections.Generic.List' to 'System.Collections.Generic.List'

Is there anyway to accomplish this?

解决方案

The reason you cannot do this is because a list is writable. Suppose it were legal, and see what goes wrong:

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!

Well dog my cats, that is badness.

The feature you want is called "generic covariance" and it is supported in C# 4 for interfaces that are known to be safe. IEnumerable<T> does not have any way to write to the sequence, so it is safe.

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

That will work in C# 4 because List<Cat> is convertible to IEnumerable<Cat>, which is convertible to IEnumerable<Animal>. There is no way that Play can use IEnumerable<Animal> to add a dog to something that is actually a list of cats.

这篇关于演员表&lt;&gt;派生类的列表&lt;&gt;基类的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆