为什么带约束的泛型扩展方法不被识别为扩展方法?

时间:2011-08-24 17:07:45

标签: c# generics extension-methods constraints

  

可能重复:
  No type inference with generic extension method

考虑两种方法:

public static IEnumerable<V> Merge<V>
       (this IEnumerable<IEnumerable<V>> coll)

public static IEnumerable<V> Merge<T, V>
       (this IEnumerable<T> coll) 
              where T : IEnumerable<V>

两种编译都很好,在这两种情况下,泛型类型的类型将在调用者的编译时知道,因此是扩展类型的确切类型。

您可以调用两者,但只能将第一个调用为扩展名。

为什么?

更新1

要查看它失败,请使用第二种方法,例如:

    var x = new List<List<int>>();
    var y = x.Merge();

更新 - 关闭

难道你们不认为原帖是太精心设计得到清晰的画面吗?出于教育目的,我认为这篇文章不应该被关闭,即使技术上(即答案)它是重复的。我的2美分。

2 个答案:

答案 0 :(得分:4)

在进行推理时,方法类型推断不会考虑约束。

昨天也提出同样的问题。有关详细信息,请参阅我的答案。

No type inference with generic extension method

答案 1 :(得分:2)

我不认为问题是第二个不能被调用,但IntelliSense不会看到它,因为它无法轻易地从您的调用中推断出第二个泛型类型参数V帮助

例如,根据您的两种扩展方法,以下都是合法的

    // IEnumerable<IEnumerable<int>> definition...
    List<List<int>> x = ...;

    // calls your first method (implicitly)
    x.Merge();

    // also calls your first method (explicitly)
    x.Merge<int>();

    // calls your second method (explicitly)
    x.Merge<List<int>, int>();

所有这三个编译成功,我只考虑两个泛型类型参数,它不能推断你的第二个泛型类型参数从使用,因此它没有显示在intellisense,但仍然合法...

UPDATE :根据提问者的说法,并不是两个方法都被声明为重载,而是它们是/或。鉴于原因Merge()在第二种形式上不起作用,因为T和V之间的关系是在类型约束中定义的,因此不像Eric在他的S.O.中所说的那样用于类型推断。答案。