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

本文关键字:类型参数 推断出 编译器 不能 用法 为什么 | 更新日期: 2023-09-27 17:50:15

这个问题是基于我的另一个问题的结果。我的新问题不是我如何让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 );

我的问题是"为什么我需要在第一个例子中显式地指定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);

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

这当然只是我偷懒,但这只是我所期望的,当编译器没有捡起我的懈怠时,我感到很惊讶。

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

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

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