为什么编译器不能从使用中推断出这种类型的参数

时间:2014-03-14 19:18:42

标签: c# .net compiler-construction delegates anonymous-function

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

我已经创建了一个简单的问题示例,但是如果您想查看我使用此功能的实际应用/情况,请查看我的original question(以下函数不要&#39 ; t实际做任何有用的事情。)

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 );

我的问题是&#34;为什么我需要为第一个示例明确指定T的{​​{1}}?&#34;我不知道这是因为编译器将前两个示例转换为相同的代码行。使用ILSpy我看到代码编译成了这个。

bar

我不明白为什么编译器不能从我只有一个名为foo的函数来推断类型,并且它确实适合模板。现在,如果我创建了另一个函数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); ,我会理解编译器是否抱怨存在歧义,并且它不知道我想要哪一个,并且我应该明确指定类型参数。

这当然只是我懒惰,但这只是我期待的事情,并且当编译器没有收拾我的懈怠时感到惊讶。

1 个答案:

答案 0 :(得分: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