所以我们有这个:
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
{ }
}
我明白为什么这不会编译:
WidgetProcessor.ProcessWidgets1(new List<Widget>());
C# 关于协变的规则明智地说它不应该,否则你可能会遇到各种顽皮,正如其他地方详细解释的那样。
但是 ProcessWidgets2:什么是...?
这是如何编译和运行的:
WidgetProcessor.ProcessWidgets2(new List<Widget>());
期待消除我的无知,但我看不出 ProcessWidgets1 和 ProcessWidgets2(实际上)有什么不同。
最佳答案
ProcessWidgets2<T>
是一种通用方法。当你用 new List<Widget>()
调用它时,编译器推断类型 T
是Widget
,它匹配约束,并调用它,因为 List<T>
工具 IList<T>
.
将其视为被分解为多个调用可能是最简单的做法:
IList<Widget> temp = new List<Widget>();
WidgetProcessor.ProcessWidgets2<Widget>(temp); // Widget is an IWidget, so this matches constraints
这里没有变化,因为 List<T>
直接实现 IList<T>
,并且您正在使用编译器推断出的特定类型进行调用。
关于C# .Net 协方差 - 为了旧时的缘故再次出现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15552203/