为什么我不能对两个泛型类型参数使用协变?

Why can't I use covariance with two generic type parameters?

考虑以下示例:

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

我收到编译器错误

Cannot convert expression type 'System.Collection.Generic.List' to return type 'System.Collection.Generic.IEnumerable'

我做错了什么?

事情是,在第一种情况下,Base 已知是 class。在第二种情况下,类型参数 T 可以是 class 或结构(这是编译器的想法)。

解决案例指定T是一个class,错误就会消失:

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 协变和逆变不使用结构.