【问题标题】:Why can't the compiler resolve these generic types为什么编译器不能解析这些泛型类型
【发布时间】:2013-02-22 15:36:32
【问题描述】:

如果我有这样的方法:

public void Foo<T1, T2>(T1 list)
    where T1 : IList<T2>
    where T2 : class
{
    // Do stuff
}

现在如果我有:

IList<string> stringList = new List<string>();
List<object> objectList = new List<object>();
IList<IEnumerable> enumerableList = new List<IEnumerable>();

然后编译器无法解析要选择的泛型并且失败:

Foo(stringList);
Foo(objectList);
Foo(enumerableList);

您必须明确指定要使用的泛型:

Foo<IList<string>, string>(stringList);
Foo<IList<object>, object>(objectList);
Foo<List<object>, object>(objectList);
Foo<IList<IEnumerable>, IEnumerable>(enumerableList);

【问题讨论】:

  • 旁白,但你真的需要T1吗?你不能public void Foo&lt;T&gt;(IList&lt;T&gt; list) where T : class吗?
  • 检查链接问题中的 Eric 答案以及其中链接的博客文章。
  • @Daniel:不关闭这个问题的一个原因,即使它是重复的,也是它简单而简约的代码示例和问题描述。原来的问题真的很难理解。
  • @lc.:很可能,您的评论是正确的,但在某些情况下,这样的事情是有道理的。一个例子是整个类层次结构的流畅扩展方法,其中扩展方法应该返回具体的子类型而不是公共接口。想象Foo 作为扩展方法返回T1。在这种情况下,以下内容将是有效的:new List&lt;...&gt;().Foo(...).AddRange()。 (注意:AddRange 是在 List&lt;T&gt; 上定义的,而不是在 IList&lt;T&gt; 上定义的。因此,如果 Foo 将返回 IList&lt;T2&gt;,则该代码将不再有效。

标签: c# generics


【解决方案1】:

通用方法类型推断故意从约束中进行任何推论。而是从 参数形参 进行推导,然后根据约束检查推导的类型参数。

有关约束和方法签名的一些设计问题的详细讨论,包括数十人告诉我认为现有设计是明智的想法是错误的,请参阅我关于该主题的文章:

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

这是Eric Lippert's answer to a similar question的精确副本。
我决定复制它,因为这个问题更简洁明了。

【讨论】:

  • 现在我们可以关闭原来的问题作为副本:-)
猜你喜欢
  • 2012-01-15
  • 2017-12-30
  • 1970-01-01
  • 2011-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多