接口作为类型约束和接口作为参数之间的区别?

Don*_*nut 13 c# generics intermediate-language type-constraints type-parameter

如果我想创建一个以实例IList作为参数(或任何其他接口,但让我们IList用作示例)的方法,我可以创建一个带有类型约束的泛型方法,例如:

public static void Foo1<T>(T list) where T : IList
{

}
Run Code Online (Sandbox Code Playgroud)

或者,我可以创建一个IList直接获取参数的方法:

public static void Foo2(IList list)
{

}
Run Code Online (Sandbox Code Playgroud)

对于所有意图和目的,似乎这些方法的行为完全相同:

List<string> myList = new List<string>();
Foo1(myList);
Foo2(myList);
Run Code Online (Sandbox Code Playgroud)

所以这是我的问题 - 这两种方法之间的区别是什么?似乎第二种方法更具可读性; 我应该注意哪些其他差异(生成不同的IL等)?提前致谢.

Jon*_*eet 11

有几点不同:

  • 如果您再次需要真实类型(例如,传递给另一个泛型方法或进行日志记录),那么泛型方法会更好
  • T可以是值类型,但最终仍然以通用形式取消装箱.这种情况几乎不可能发生IList,但对于其他接口来说,这是非常合理的
  • 通用表单允许您指定与实际对象类型不同的具体实现类型.例如,你可能会传递一个空引用,但还是想知道哪一个实现类T
  • 他们将被不同地JIT; 请参阅Joe Duffy 最近关于泛型博客文章以获取更多信息

这当然取决于你正在做什么......除非你真的需要T在方法中知道任何事情,否则通用形式的唯一好处就是拳击点.