考虑两种方法:
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>
两种编译都很好,在这两种情况下,泛型类型的类型将在调用者的编译时知道,因此是扩展类型的确切类型。
您可以调用两者,但只能将第一个调用为扩展名。
为什么?
要查看它失败,请使用第二种方法,例如:
var x = new List<List<int>>();
var y = x.Merge();
难道你们不认为原帖是太精心设计得到清晰的画面吗?出于教育目的,我认为这篇文章不应该被关闭,即使技术上(即答案)它是重复的。我的2美分。
答案 0 :(得分:4)
答案 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.中所说的那样用于类型推断。答案。