C#.Net Covariance - 再次出现旧时的缘故?

Mat*_*att 3 .net c# covariance contravariance

所以我们有这个:

public interface IWidget
{
    int Id { get; set; }
}

public class Widget : IWidget
{
    public int Id { get; set; }
}

public class WidgetProcessor
{
    public static void ProcessWidgets1(IList<IWidget> widgets)
    { }

    public static void ProcessWidgets2<T>(IList<T> widgets) where T : IWidget
    { }
}
Run Code Online (Sandbox Code Playgroud)

我明白为什么这不会编译: WidgetProcessor.ProcessWidgets1(new List<Widget>()); C#规则围绕协方差明智地说它不应该,或者你可以得到各种各样的顽皮,正如其他地方详细解释的那样.

但是ProcessWidgets2:什么......?
它是如何,这确实编译和运行: WidgetProcessor.ProcessWidgets2(new List<Widget>());

期待我的无知被删除,但我无法看到ProcessWidgets1和ProcessWidgets2(有效地)有何不同.

Ree*_*sey 5

ProcessWidgets2<T>是一种通用方法.当你调用它时new List<Widget>(),编译器推断出类型TWidget匹配约束的类型,并且调用它,因为List<T>实现IList<T>.

最好看一下它就好像被分解成多个调用一样:

IList<Widget> temp = new List<Widget>();
WidgetProcessor.ProcessWidgets2<Widget>(temp); // Widget is an IWidget, so this matches constraints
Run Code Online (Sandbox Code Playgroud)

这里没有任何差异,因为List<T>直接实现IList<T>,并且您使用由编译器推断的特定类型进行调用.