为什么我不能使用两个泛型类型参数的协方差?

时间:2015-02-11 14:46:35

标签: c# generics covariance

考虑以下示例:

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;
    }
}

我收到编译错误

  

无法转换表达式类型   &#39; System.Collection.Generic.List&#39;返回类型   &#39; System.Collection.Generic.IEnumerable&#39;

我在这里做错了什么?

1 个答案:

答案 0 :(得分:14)

事情是,在第一种情况下,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约束)和as we already know协方差和逆变不适用于结构