以下调用重载的Enumerable.Select
方法:
var itemOnlyOneTuples = "test".Select<char, Tuple<char>>(Tuple.Create);
因模糊错误而失败(为清晰起见,删除了名称空间):
The call is ambiguous between the following methods or properties:
'Enumerable.Select<char,Tuple<char>>
(IEnumerable<char>,Func<char,Tuple<char>>)'
and
'Enumerable.Select<char,Tuple<char>>
(IEnumerable<char>, Func<char,int,Tuple<char>>)'
我当然可以理解为什么不明确指定类型参数会导致歧义(这两种情况都会适用),但是在这样做之后我没有看到。
我觉得很清楚,目的是调用第一个重载,方法组参数解析为Tuple.Create<char>(char)
。第二个重载不应该适用,因为Tuple.Create
重载都不能转换为预期的Func<char,int,Tuple<char>>
类型。我是猜测编译器被Tuple.Create<char, int>(char, int)
混淆了,但是它的返回类型是错误的:它返回一个二元组,因此不能转换为相关的Func
类型。
顺便说一下,以下任何一个都让编译器感到高兴:
Tuple.Create<char>
(也许这实际上是一个类型推断问题?)。x => Tuple.Create(x)
。 (在Select
电话中使用类型推断很好。不出所料,尝试以这种方式调用Select
的其他重载也会失败:
var itemIndexTwoTuples = "test".Select<char, Tuple<char, int>>(Tuple.Create);
这里的确切问题是什么?
答案 0 :(得分:20)
答案 1 :(得分:5)
我猜测编译器被
Tuple.Create<char, int>(char, int)
搞糊涂了,但它的返回类型是错误的:它返回一个两元组。
返回类型不是方法签名的一部分,因此在重载解析期间不会考虑它;只有在选择了重载后才会验证。因此,就编译器所知,Tuple.Create<char, int>(char, int)
是一个有效的候选者,它既不比Tuple.Create<char>(char)
好也不差,所以编译器无法决定。