C#泛型重载 - 编译器不能确定正确的调用 [英] C# generic overload - Compiler can't determine correct call

查看:241
本文介绍了C#泛型重载 - 编译器不能确定正确的调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白为什么编译器无法解析正确的超负荷用在这里。 (下面的代码)只有一种()版本添加的是适当而BigFoo是IFoo的,并没有实现IEnumerable,其中T是一个IFoo的。但它坚持报告的不确定性。有任何想法吗?我尝试添加第二个泛型类型参数 - 加入其中,T:IFoo的其中U:IEnumerable的。但随后的过载是完全即使是合法使用忽略。



我知道我可以解决这个具有铸造并指定泛型参数,但在这一点上我有击败过载的目的。你可以质疑过载,但语义觉得正确的我 - 我实施班里的行为是对于Add()对象批发添加为集合中的单个条目。 (第二个Add()不应该是一个的AddRange()。)

 命名空间NS 
{
接口的IFoo {}

类BigFoo:IFoo的,IEnumerable的< INT>
{
公众的IEnumerator< INT>的GetEnumerator()
{
抛出新NotImplementedException();
}
的IEnumerator IEnumerable.GetEnumerator()
{
抛出新NotImplementedException();
}
}

类FooContainer
{
公共无效添加(的IFoo项目){}
公共无效添加< T>(IEnumerable的< ; T&基团),其中T:的IFoo {}
}

类DemoClass
{
无效DemoMethod()
{
bigFoo bigFoo =新BigFoo();
FooContainer fooContainer =新FooContainer();
//错误CS0121:呼叫是以下方法或属性之间暧昧:
//'NS.FooContainer.Add(NS.IFoo)'和
//'NS.FooContainer。添加<&诠释GT;(System.Collections.Generic.IEnumerable< INT>)
fooContainer.Add(bigFoo);
}
}
}


解决方案

通用重载决议没有考虑约束考虑在内,所以它认为的添加< T> 版本适用,推断 T = INT



这两种方法都适用,也不是绝对比其他更好的,因为有之间不存在转换IEnumerable的< INT> 的IFoo 。虽然通用的方法被认为比非泛型方法不具体,当参数类型的类型参数的更换,他们在这种情况下,你不相同后,这只变得相关。


I don't understand why the compiler can't resolve the correct overload to use here. (code below) There is only one version of Add() that is appropriate- BigFoo is an IFoo, and does not implement IEnumerable where T is an IFoo. But it insists on reporting an ambiguity. Any ideas? I tried adding a second generic type parameter- Add where T : IFoo where U : IEnumerable. But then the overload is completely ignored even for legitimate use.

I know I can work around this with casting and specifying generic type parameters but at that point I've defeated the purpose of having an overload. You could question the overload, but the semantics feel correct to me- the behavior I'm implementing in my class is for both Add() to add the object wholesale as an individual entry in the collection. (the second Add() is not supposed to be an 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);
    }
  }
}

解决方案

Generic overload resolution doesn't take constraints into account, so it deems the Add<T> version to be applicable, inferring T=int.

Both methods are applicable, and neither is definitely better than the other, as there is no conversion between IEnumerable<int> and IFoo. While generic methods are deemed "less specific" than non-generic methods, this only becomes relevant when the parameter types are identical after type argument replacement, which they're not in this case.

这篇关于C#泛型重载 - 编译器不能确定正确的调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆