为什么编译器不能从用法中推断出这个类型参数

问题描述 投票:0回答:1

这个问题是基于我的另一个SO问题的结果。我的新问题不是如何让 X 工作的问题,而是为什么 X 不起作用。

我已经创建了我的问题的简化示例,但是如果您想了解我正在使用它的实际应用/情况,请查看我的原始问题(以下函数实际上没有做任何有用的事情)。

T bar<T>(Func<T, bool> f) { return default(T); }
bool foo(int i) { return true; }

现在我有 3 行代码可以按预期工作,并且全部都出于相同目的执行相同的操作。

int num;
num = bar<int>(foo);
num = bar(new Func<int, bool>(foo));
num = bar((int i) => true );

我的问题是“为什么我需要为第一个示例的

T
显式指定
bar
?”我想知道这一点的原因是因为编译器将前两个示例转换为同一行代码。使用 ILSpy 我看到代码编译为这样。

num = Program.bar<int>(new Func<int, bool>(Program.foo));
num = Program.bar<int>(new Func<int, bool>(Program.foo));
num = Program.bar<int>((int i) => true);

我不明白为什么编译器无法从我只有一个名为 foo 的函数这一事实推断出类型,并且可以说它确实适合模板。现在,如果我创建了另一个函数

bool foo(bool i)
,如果编译器抱怨存在一些歧义,并且它不知道我想要哪个函数,并且我应该明确指定类型参数,我就会理解。

这当然只是我的懒惰,但这只是我所期待的事情,并且当编译器没有弥补我的不足时我感到很惊讶。

c# .net delegates anonymous-function
1个回答
5
投票

我在公交车上,所以简短回答。

t 的类型推断需要知道参数中委托类型的形参类型。

方法组到委托类型的转换会进行重载解析,就像使用目标委托的形式参数类型的实参调用方法组一样。

但这些类型正是我们试图推断的!

这是循环推理,因此类型推断拒绝它。方法组转换要求从其他参数推导出形式参数类型。

你没有其他论据。

所以推理失败。

该组仅包含一种方法是无关紧要的。如果向组中添加更多方法导致推理失败,那就很奇怪了。通过重载决议来解决一组重载的规则是一个明智的规则,并且需要知道参数。您不能仅仅因为方法组恰好是单例就向后运行推理。

请参阅我的 msdn 博客上的类型推断标签,了解有关此主题的较长文章。

http://blogs.msdn.com/b/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx

© www.soinside.com 2019 - 2024. All rights reserved.