将派生类赋值给具有泛型的基类变量
本文关键字:泛型 基类 类变量 派生 赋值 | 更新日期: 2023-09-27 18:16:33
我有一组具有相对简单的层次结构的类和接口,但是有继承的东西,然后有一个接受基类的变量不能很好地工作。我认为问题是我的动态类型必须是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;
不能隐式或显式强制转换this。
我怎样才能使它工作?
您的接口不是协变有效的。也就是说,
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+)
您需要更改class B
的定义如下:
public abstract class B<X, Y> : A, IB<X, Y> where X : class where Y : class
{
...
}
约束必须在整个继承链中指定。