考虑以下示例:
class Base {}
class Derived : Base {}
class Test1
{
private List<Derived> m_X;
public IEnumerable<Base> GetEnumerable()
{
return m_X;
}
}
这编译得很好,因为IEnumerable<T>
在T
中是协变。
然而,如果我做完全相同的事情,但现在使用泛型:
class Test2<TBase, TDerived> where TDerived : TBase
{
private List<TDerived> m_X;
public IEnumerable<TBase> GetEnumerable()
{
return m_X;
}
}
我得到了编译器错误
无法转换表达式类型"System.Collection.Generic.List"以返回类型"System.Collection.Generic.IENumberable"
我在这里做错了什么?
在第一种情况下,Base
已知为一个类。在第二种情况下,类型参数T
可以是类或结构(这就是编译器的想法)。
通过指定T
是一个类来解决此问题,错误将消失:
class Test2<TBase, TDerived> where TDerived : class, TBase
{
private List<TDerived> m_X;
public IEnumerable<TBase> GetEnumerable()
{
return m_X;
}
}
因此,编译器试图向我们展示TDerived可以是一个结构(因为您没有指定class
约束),并且正如我们已经知道的,协方差和逆变差不适用于结构。