继承和泛型约束

本文关键字:约束 泛型 继承 | 更新日期: 2023-09-27 18:02:14

我一直在与集合、泛型和继承作斗争。对不起,但我不确定如何以适当的方式表达我的问题,但我确信这段代码足以显示它。

public class A
{
    public IList<C> sequenceOfC;
    public A(IList<C> sequenceOfC)
    {
        this.sequenceOfC = sequenceOfC;
    }
}
public class B : A {
    public B(IList<D> sequanceOfC) : base(sequanceOfC) { } //compile time error 
    // Error 2  Argument 1: cannot convert from 
    // 'System.Collections.Generic.IList<ConsoleApplication.D>' 
    // to 'System.Collections.Generic.IList<ConsoleApplication.C>'  
}
public class C { }
public class D : C { }

我不明白为什么我看到这个错误。D是从C遗传而来的,一切都应该继续下去,不是吗?

继承和泛型约束

问题是IList不是协变的。因此编译器不能保证D在任何情况下都能转换成C。解决方案是使用IEnumerable<C>初始化列表:

public class A
{
    public IList<C> sequanceOfC;
    public A(IEnumerable<C> sequanceOfC)
    {
        this.sequanceOfC = new List<C>(sequanceOfC);
    }
}
public class B : A 
{
    public B(IList<D> sequanceOfD) : base(sequanceOfD) { }  
}

如果D继承自C,并且IList是协变的,您将能够编写:

public class E : C
{}
IList<D> source = new List<D>();
IList<C> target = source;
target.Add(new E());

这显然是错误的,因为您将在D列表中添加E