我有一组类和接口,它们具有相对简单的层次结构,但是有东西继承,然后有一个接受基类的变量不能正常工作。我认为问题是我的动态类型必须是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;
不能暗中或明确地施展这一点。
我怎样才能让它发挥作用?
答案 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
{
...
}
必须在整个继承链中指定约束。