【问题标题】:C# overloading with generics: bug or feature?C# 使用泛型重载:错误还是特性?
【发布时间】:2011-02-04 21:53:24
【问题描述】:

让我们有一个简化的例子:

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);
}

它会正常工作的。为什么编译器不选择right重载?

【问题讨论】:

  • IEnumerable 和 ICollection 之间确实没有转换。
  • @Yossarian:两件事。首先,有一个显式转换。您的意思是说“确实没有隐式引用转换”。其次,问题不是“为什么我会收到‘无隐式转换’错误?”其次,问题是“为什么重载解决算法会选择一个无效的完全匹配候选而不是选择不完全匹配的有效但更差的候选?”

标签: c# generics c#-3.0 constraints overloading


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 2012-01-05
    • 1970-01-01
    • 2014-12-15
    • 1970-01-01
    • 2014-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多