我有一些域和元素的接口和类:
interface IElement {}
class FloatElement : IElement {}
interface IDomain<T> where T: IElement {}
class FloatDomain : IDomain<FloatElement>
{
public static readonly FloatDomain Instance = new FloatDomain();
}
我写了这个
IDomain<IElement> foo = FloatDomain.Instance;
但收到了错误:
(CS0266)&#34;无法隐式转换类型[...]。显式转换 存在(你错过了演员?)&#34;
(请注意,尽管有提示&#34;存在显式转换&#34;,FloatDomain.Instance as IDomain<IElement>
将返回null
。)
我已经发现我可以通过FloatDomain
实现IDomain<IElement>
来解决此问题。 但我想知道为什么这种解决方法是必要的!
据我了解,FloatElement
是IElement
的更专业版,即我可以隐式地将FloatElement
转换为IElement
。因此,IDomain<FloatElement>
是IDomain<IElement>
的更专业版本,即我也应该能够隐式地将IDomain<FloatElement>
转换为IDomain<IElement>
。
或者换句话说:在我的理解中,IDomain<IElement>
就像IDomain<T>
实现T
的所有其他IElement
的基类,因为T=IElement
是最普遍的情况。
你能指出我的推理错误吗?
答案 0 :(得分:3)
您尝试做的事情称为差异。在C#中,默认情况下接口不是变体,这就是你得到编译错误的原因。您可以将您的界面明确标记为协变或逆变,以使其有效:
interface IDomain<in T> where T: IElement {}
interface IDomain<out T> where T: IElement {}
有关详细信息,请参阅Variance in Generic Types。