使用genericsC#重载:错误还是function?

我们有一个以下简化示例:

void Foo(IEnumerable collection, params T[] items) { // ... } void Foo(C collection, T item) where C : ICollection { // ... } void Main() { Foo((IEnumerable)new[] { 1 }, 2); } 

编译说:

类型’System.Collections.Generic.IEnumerable’不能在generics类型或方法’UserQuery.Foo(C,T)’中用作类型参数’C’。 没有从’System.Collections.Generic.IEnumerable’到’System.Collections.Generic.ICollection’的隐式引用转换。

如果我将Main更改为:

 void Main() { Foo((IEnumerable)new[] { 1 }, 2); } 

它会工作正常。 为什么编译器没有选择正确的重载?

你的问题在这里得到解答。

http://blogs.msdn.com/ericlippert/archive/2009/12/10/constraints-are-not-part-of-the-signature.aspx

还请阅读大约一百万条评论告诉我,我对这个问题的一些有趣的额外评论是错误的。

我的猜测是编译器在使用generics约束之前选择最佳匹配。 在您的示例中,具有约束的方法更可取,因为它没有params last参数。

编辑 – Eric Lippert在他的回答中证实了这一点。