让我们有一个简化的例子:
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);
}
编译说:
类型'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);
}
它会正常工作。为什么编译器不选择正确重载?
答案 0 :(得分:15)
你的问题在这里得到解答。
http://blogs.msdn.com/ericlippert/archive/2009/12/10/constraints-are-not-part-of-the-signature.aspx
还请阅读大约一百万条评论,告诉我在这个问题上有一些有趣的补充评论我错了。
答案 1 :(得分:2)
我的猜测是编译器在使用泛型约束之前选择最佳匹配。在您的示例中,带有约束的方法更可取,因为它没有params
最后一个参数。
编辑 - Eric Lippert在答案中证实了这一点。