我有以下课程:
public abstract class ThingBase { }
public class ThingA : ThingBase { }
以下通用类:
public class ThingOwner<ThingType> where ThingType : ThingBase { }
我想创建一个ThingOwner实例,如下所示:
ThingOwner<ThingBase> thingOwner = new ThingOwner<ThingA>();
使用此代码,我收到以下错误:“无法将类型'ThingOwner(ThingA)'隐式转换为'ThingOwner(ThingBase)'”。
我无法想象如何让它发挥作用。我知道有很多关于泛型类和继承的现有讨论,但我几乎尝试了所有内容,但我找不到适用于我的解决方案。
谢谢!
答案 0 :(得分:3)
您应该使用C#4.0中引入的covariance for generic types。为此,您需要使用接口而不是类:
public interface IThingOwner<out ThingType> where ThingType : ThingBase { }
public class ThingOwner<ThingType> : IThingOwner<ThingType>
where ThingType : ThingBase
{
}
IThingOwner<ThingBase> thingOwner = new ThingOwner<ThingA>();
答案 1 :(得分:1)
仅支持接口的协方差/逆变。如果你需要课程,那么只有这些课程可以工作:
ThingOwner<ThingBase> thingOwner = new ThingOwner<ThingBase>();
ThingOwner<ThingA> thingOwner = new ThingOwner<ThingA>();
答案 2 :(得分:1)
除上述答案外还有一些解释。虽然您的问题可以理解,但请考虑以下事项:
声明您有一个接受类型参数ClassA
的派生类。在ThingOwner<ClassA>
中,只允许添加一个或来自ClassA
的类的实例。当您将其转换为ThingOwner<BaseClass>
时,突然允许添加ClassB
的实例,该实例也来自BaseClass
。这可能会损害您的程序,实际上是错误的。这就是为什么他们首先发明了仿制药。