C#泛型继承问题 [英] C# Generics Inheritance Problem

查看:109
本文介绍了C#泛型继承问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想不同类型从泛型一个类派生的对象加入到基类型的List。我得到这个编译错误

 错误2参数1:无法从ConsoleApplication1.Stable'转换为'ConsoleApplication1.ShelterBase< ConsoleApplication1。 AnimalBase>'C:\Users\ysn\Desktop\ConsoleApplication1\ConsoleApplication1\Program.cs 43 26 ConsoleApplication1 

我看不到这个问题你能提供给我做这种事情的另一种方式?

 抽象类AnimalBase {公众诠释SomeCommonProperty;} 

抽象类ShelterBase< T>其中T:AnimalBase
{
公共抽象列表< T> GetAnimals();
公共抽象无效FeedAnimals(列表< T>动物);
}


级马:AnimalBase {}

级稳定:ShelterBase<马>
{
公众覆盖列表<马> GetAnimals()
{
返回新的List<马>();
}

公共覆盖无效FeedAnimals(列表<马>动物)
{
//喂它们
}
}


级鸭:AnimalBase {}

类鸡舍:ShelterBase<鸭肉GT;
{
公众覆盖列表<鸭肉GT; GetAnimals()
{
返回新的List<鸭肉GT;();
}

公共覆盖无效FeedAnimals(列表<鸭>动物)
{
//喂它们
}
}

类项目
{
静态无效的主要(字串[] args)
{
名单,LT; ShelterBase< AnimalBase>>候车亭=新的List< ShelterBase< AnimalBase>>();下面两行不执行编译


///////////////////////////// shelters.Add (新的稳定());
shelters.Add(新鸡舍());
/////////////////////////////

的foreach(在避难所避难VAR)
{
变种动物= shelter.GetAnimals();
//做某事与'动物'收集
}
}
}


解决方案

您可以使用的逆变,但是的只有的,如果你改变你的抽象类的接口和返回类型 GetAnimals 的IEnumerable< T> ,因为列表< T> 不支持此功能。

该工程

代码:

 抽象类AnimalBase {公众诠释SomeCommonProperty;} 

接口IShelterBase<出T>其中T:AnimalBase
{
IEnumerable的< T> GetAnimals();
}

级马:AnimalBase {}

级稳定:IShelterBase<马>
{
公开的IEnumerable<马> GetAnimals()
{
返回新的List<马>();
}
}

级鸭:AnimalBase {}

类鸡舍:IShelterBase<鸭肉GT;
{
公开的IEnumerable<鸭肉GT; GetAnimals()
{
返回新的List<鸭肉GT;();
}
}

无效的主要()
{
名单,LT; IShelterBase< AnimalBase>>候车亭=新的List< IShelterBase< AnimalBase>>();

shelters.Add(新的稳定());
shelters.Add(新鸡舍());

的foreach(在避难所避难VAR)
{
变种动物= shelter.GetAnimals();
//做'动物'收集
}
}


的东西

I'd like to add different types of objects derived from one class with generics into a List of base type. I get this compile error

Error   2   Argument 1: cannot convert from 'ConsoleApplication1.Stable' to 'ConsoleApplication1.ShelterBase<ConsoleApplication1.AnimalBase>'   C:\Users\ysn\Desktop\ConsoleApplication1\ConsoleApplication1\Program.cs 43  26  ConsoleApplication1

I can't see the problem could you provide me an alternative way of doing this kind of thing?

abstract class AnimalBase { public int SomeCommonProperty;}

abstract class ShelterBase<T> where T : AnimalBase
{
    public abstract List<T> GetAnimals();
    public abstract void FeedAnimals(List<T> animals);
}


class Horse : AnimalBase { }

class Stable : ShelterBase<Horse>
{
    public override List<Horse> GetAnimals()
    {
        return new List<Horse>();
    }

    public override void FeedAnimals(List<Horse> animals)
    {
        // feed them
    }
}


class Duck : AnimalBase { }

class HenHouse : ShelterBase<Duck>
{
    public override List<Duck> GetAnimals()
    {
        return new List<Duck>();
    }

    public override void FeedAnimals(List<Duck> animals)
    {
        // feed them
    }
}

class Program
{
    static void Main(string[] args)
    {
        List<ShelterBase<AnimalBase>> shelters = new List<ShelterBase<AnimalBase>>();

        ///////////////////////////// following two lines do not compile
        shelters.Add(new Stable()); 
        shelters.Add(new HenHouse());
        /////////////////////////////

        foreach (var shelter in shelters)
        {
            var animals = shelter.GetAnimals();
            // do sth with 'animals' collection
        }
    }
}

解决方案

You can use contravariance, but only if you change your abstract class to an interface and the return type of GetAnimals to an IEnumerable<T>, because List<T> doesn't support this feature.

Code that works:

abstract class AnimalBase { public int SomeCommonProperty;}

interface IShelterBase<out T> where T : AnimalBase
{
    IEnumerable<T> GetAnimals();
}

class Horse : AnimalBase { }

class Stable : IShelterBase<Horse>
{
    public IEnumerable<Horse> GetAnimals()
    {
        return new List<Horse>();
    }
}

class Duck : AnimalBase { }

class HenHouse : IShelterBase<Duck>
{
    public IEnumerable<Duck> GetAnimals()
    {
        return new List<Duck>();
    }
}

void Main()
{
    List<IShelterBase<AnimalBase>> shelters = new List<IShelterBase<AnimalBase>>();

    shelters.Add(new Stable());
    shelters.Add(new HenHouse());

    foreach (var shelter in shelters)
    {
        var animals = shelter.GetAnimals();
        // do something with 'animals' collection
    }
}

这篇关于C#泛型继承问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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