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

Ben*_*dgi 3 .net c# compiler-construction delegates anonymous-function

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

我已经创建了一个简单的问题示例,但是如果你想看到我正在使用它的实际应用/情况,请查看我原来的问题(下面的函数实际上并没有做任何有用的事情).

T bar<T>(Func<T, bool> f) { return default(T); }
bool foo(int i) { return true; }
Run Code Online (Sandbox Code Playgroud)

现在我有3行代码可以按预期工作,并且所有目的都是明智的.

int num;
num = bar<int>(foo);
num = bar(new Func<int, bool>(foo));
num = bar((int i) => true );
Run Code Online (Sandbox Code Playgroud)

我的问题是:"为什么我需要明确指定Tbar第一个例子吗?" 我不知道这是因为编译器将前两个示例转换为相同的代码行.使用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);
Run Code Online (Sandbox Code Playgroud)

我不明白为什么编译器不能从我只有一个名为foo的函数来推断类型,并且它确实适合模板.现在,如果我创建了另一个函数,bool foo(bool i)我会理解,如果编译器抱怨存在一些歧义,并且它不知道我想要哪一个,并且我应该明确指定类型参数.

这当然只是我的懒惰,但它只是我期待的东西,当编译器没有恢复我的松弛时感到惊讶.

Eri*_*ert 5

我在公共汽车上,所以,简短的回答.

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

将方法组转换为委托类型会执行重载解析,就好像使用目标委托的形式参数类型的参数调用方法组一样.

但那些类型是我们想要推断的!

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

你没有其他论据.

所以推断失败了.

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

请参阅我的msdn博客上的类型推断标记,以获取有关此主题的更长篇文章.

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