使用泛型C#重载:错误还是功能?

TN.*_*TN. 8 c# generics overloading constraints c#-3.0

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

void Foo<T>(IEnumerable<T> collection, params T[] items) 
{
    // ...
}

void Foo<C, T>(C collection, T item)
    where C : ICollection<T>
{
    // ...
}

void Main()
{
    Foo((IEnumerable<int>)new[] { 1 }, 2);
}
Run Code Online (Sandbox Code Playgroud)

编译说:

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

如果我Main改为:

void Main()
{
    Foo<int>((IEnumerable<int>)new[] { 1 }, 2);
}
Run Code Online (Sandbox Code Playgroud)

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

Eri*_*ert 15

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

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

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


Ben*_*ngs 2

我的猜测是编译器在使用通用约束之前会选择最佳匹配。在您的示例中,带有约束的方法更好,因为它没有params最后一个参数。

编辑-埃里克·利珀特在他的回答中证实了这一点。