如何创建具有继承的泛型类?

kev*_*aub 1 c# inheritance covariance contravariance

如何使以下代码有效?我不认为我完全理解C#泛型.也许,有人可以指出我正确的方向.

    public abstract class A
    {
    }

    public class B : A
    {
    }

    public class C : A
    {
    }

    public static List<C> GetCList()
    {
        return new List<C>();
    }

    static void Main(string[] args)
    {
        List<A> listA = new List<A>();

        listA.Add(new B());
        listA.Add(new C());

        // Compiler cannot implicitly convert
        List<A> listB = new List<B>();

        // Compiler cannot implicitly convert
        List<A> listC = GetCList();

        // However, copying each element is fine
        // It has something to do with generics (I think)
        List<B> listD = new List<B>();
        foreach (B b in listD)
        {
            listB.Add(b);
        }
    }
Run Code Online (Sandbox Code Playgroud)

这可能是一个简单的答案.

更新:首先,这在C#3.0中是不可能的,但在C#4.0中是可能的.

要使它在C#3.0中运行,这只是一种解决方法直到4.0,请使用以下命令:

        // Compiler is happy
        List<A> listB = new List<B>().OfType<A>().ToList();

        // Compiler is happy
        List<A> listC = GetCList().OfType<A>().ToList();
Run Code Online (Sandbox Code Playgroud)

Eri*_*ert 5

这不起作用的原因是因为它无法确定是安全的.假设你有

List<Giraffe> giraffes = new List<Giraffe>();
List<Animal> animals = giraffes; // suppose this were legal.
// animals is now a reference to a list of giraffes, 
// but the type system doesn't know that.
// You can put a turtle into a list of animals...
animals.Add(new Turtle());  
Run Code Online (Sandbox Code Playgroud)

嘿,你只是把一只乌龟放入长颈鹿名单中,现在已经违反了类型系统的完整性.这就是为什么这是非法的.

这里的关键是"动物"和"长颈鹿"指的是相同的对象,而该对象是长颈鹿的列表.但是长颈鹿的名单不能像动物名单那么多; 特别是它不能包含乌龟.

  • @Dabblernl:首先你有一个长颈鹿的名单,比如变量L1.然后你有一个动物列表相同的列表,比如变量L2.你做L2.Add(new Turtle()).这将它添加到列表本身,因此L1和L2指向的列表最后都有一只乌龟.现在你做L1 [32] .LongNeck(),编译器认为应该没问题:L1是长颈鹿的列表.但是,项目32是那只没有长脖子的乌龟.因此,根据C#类型系统的保证,您将收到不应发生的运行时错误. (3认同)