C#泛型重载 - 编译器无法确定正确的调用

Ale*_*xis 5 c# generics overloading

我不明白为什么编译器无法解决在这里使用的正确重载.(下面的代码)只有一个版本的Add()是合适的--BigFoo是一个IFoo,并且没有实现IEnumerable,其中T是一个IFoo.但它坚持要报告歧义.有任何想法吗?我尝试添加第二个泛型类型参数 - 添加其中T:IFoo其中U:IEnumerable.但即使合法使用,过载也完全被忽略.

我知道我可以通过强制转换和指定泛型类型参数解决这个问题,但那时我已经打败了过载的目的.你可以质疑重载,但语义对我来说是正确的 - 我在我的类中实现的行为是Add()将对象批量添加为集合中的单个条目.(第二个Add()不应该是AddRange().)

namespace NS
{
  interface IFoo { }

  class BigFoo : IFoo, IEnumerable<int>
  {
    public IEnumerator<int> GetEnumerator()
    {
      throw new NotImplementedException();
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
      throw new NotImplementedException();
    }
  }

  class FooContainer
  {
    public void Add(IFoo item) { }
    public void Add<T>(IEnumerable<T> group) where T : IFoo { }
  }

  class DemoClass
  {
    void DemoMethod()
    {
      BigFoo bigFoo = new BigFoo();
      FooContainer fooContainer = new FooContainer();
      // error CS0121: The call is ambiguous between the following methods or properties: 
      // 'NS.FooContainer.Add(NS.IFoo)' and 
      // 'NS.FooContainer.Add<int>(System.Collections.Generic.IEnumerable<int>)'
      fooContainer.Add(bigFoo);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 6

通用重载解析不考虑约束,因此它认为Add<T>版本适用,推断T=int.

这两种方法都适用,并且两种方法都不比其他方法更好,因为在IEnumerable<int>和之间没有转换IFoo.虽然泛型方法被认为比非泛型方法"更不具体",但只有在类型参数替换后参数类型相同时才会变得相关,在这种情况下它们不是.