C#使用泛型将派生类赋值给基类变量

时间:2011-12-02 15:03:22

标签: c# generics inheritance

我有一组类和接口,它们具有相对简单的层次结构,但是有东西继承,然后有一个接受基类的变量不能正常工作。我认为问题是我的动态类型必须是where : class而不是where : IEntity,因为这些类型用于我无法更改的函数。

public interface IB<X, Y> 
    where X : class, IEntity 
    where Y : class, IEntity
{
    ...
}

public abstract class A
{
    ...
}

public abstract class B<X, Y> : A, IB<X, Y> 
    where X : class, IEntity 
    where Y : class, IEntity
{
    ...
}

public interface IEntity
{
    ...
}

public class Entity1 : IEntity
{
    ...
}

public class Entity2 : IEntity
{
    ...
}

public class C : B<Entity1, Entity2>, IB<Entity1, Entity2>
{
   ...
}

然后,尝试在函数中使用所有这些......

C c = new C();
IB<IEntity, IEntity> ib = c;

不能暗中或明确地施展这一点。

我怎样才能让它发挥作用?

2 个答案:

答案 0 :(得分:3)

您的界面不具有协同有效性。也就是说,

IB<IEntity, IEntity>IB<Entity1, Entity2>不是一回事。要解决此问题,您可以在接口定义

中的类型参数上使用out关键字
public interface IB<out X, out Y> where X : class where Y : class

作为次要点,您需要将约束级联到B类

public abstract class B<X, Y> : A, IB<X, Y> where X : class where Y : class

通过这些更改,您将C分配到ib是合法的。

C c = new C(); 
IB<IEntity, IEntity> ib = c;

(正如Davy8在评论中正确指出的那样,这个界面协方差特征需要C#4 +。)

答案 1 :(得分:0)

您需要更改class B的定义,如下所示:

public abstract class B<X, Y> : A, IB<X, Y> where X : class where Y : class 
{
    ...
}

必须在整个继承链中指定约束。