C#类型转换错误,尽管通用约束

acd*_*cdx 3 c# generics constraints type-conversion covariance

为什么,对于"必须从A继承"的类P的类型参数T的通用约束,第一次调用成功但第二次调用失败,注释中详细说明了类型转换错误:

abstract class A { }

static class S
{
    public static void DoFirst(A argument) { }
    public static void DoSecond(ICollection<A> argument) { }
}

static class P<T>
    where T : A, new()
{
    static void Do()
    {
        S.DoFirst(new T());             // this call is OK

        S.DoSecond(new List<T>());      // this call won't compile with:

        /* cannot convert from 'System.Collections.Generic.List<T>'
           to 'System.Collections.Generic.ICollection<A>' */
    }
}
Run Code Online (Sandbox Code Playgroud)

如果不是通用约束保证List<T> 真的ICollection<A>

And*_*are 7

这是C#在泛型类型上缺乏协方差的一个例子(C#确实支持数组协方差).C#4将在接口类型上添加此功能,并且还将更新多个BCL接口类型以支持它.

请参阅C#4.0:协方差和逆变:

在本文中,我将尝试介绍一种C#4.0创新.其中一个新功能是类型参数的协方差和逆变,现在由通用委托和通用接口支持.首先让我们看看这些词是什么意思:)

  • 这在C#4.0中不会改变.`IList <T>`和`ICollection <T>`是_not covariant_.因此,尽管C#4.0将增加对类型协方差的支持,但这种特殊情况将无法正常工作. (4认同)