为什么带约束的通用扩展方法不被识别为扩展方法?
可能的重复:
通用扩展方法不进行类型推断
考虑两种方法:
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分钱。
Possible Duplicate:
No type inference with generic extension method
Consider two methods:
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>
Both compile just fine, in both cases the type of generic types will be known at compile time of caller, and thus the exact type of extended type.
You can call both fine, but only the first one as extension.
Why?
Update 1
To see it fail, use the second method and such example:
var x = new List<List<int>>();
var y = x.Merge();
Update -- closing
Don't you guys think the original post is WAY too elaborate to get the clear picture? For educational purposes I think this post shouldn't be closed, even if technically (i.e. the answer) it is duplicate. Just my 2 cents.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
方法类型推断在进行推断时不考虑约束。
昨天有人问了同样的问题。请参阅我的回答以了解更多详细信息。
通用扩展方法不进行类型推断
Method type inference does not take constraints into account when making inferences.
This same question was asked yesterday. See my answer there for more details.
No type inference with generic extension method
我不认为问题在于第二个不能被调用,而是 IntelliSense 不会看到它,因为它无法在没有显式调用的情况下轻松推断出第二个泛型类型参数
V
帮助。例如,给定您的两个扩展方法,以下都是合法的
所有这三个都编译成功,我只是认为使用两个泛型类型参数,它无法从用法中推断出您的第二个泛型类型参数因此它没有在智能感知中显示,但仍然合法...
更新:根据提问者的说法,这不是这两个方法被声明为重载,而是它们是非此即彼。鉴于这个原因, Merge() 不适用于第二种形式,因为 T 和 V 之间的关系是在类型约束中定义的,因此不用于类型推断,如 Eric 在他的 SO 答案中所述。
I don't think the problem is that the second CAN'T be called, but that IntelliSense won't see it because it can't easily infer the second generic type parameter
V
from your call without explicit help.For example, given your two extension methods, the following are all legal
All three of these compile successfully, I just think with the two generic type parameters, it can't infer your second generic type parameter from usage and thus it's not showing in intellisense, but still legal...
UPDATE: As per the asker, it's not that the two methods were declared as overloads, but that they were either/or. Given that reason Merge() doesn't work on the 2nd form because the relationship between T and V are defined in the type constraints, and thus are not used for type inference as Eric stated in his S.O. answer.