这个问题是基于我的另一个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);
,我会理解编译器是否抱怨存在歧义,并且它不知道我想要哪一个,并且我应该明确指定类型参数。
这当然只是我懒惰,但这只是我期待的事情,并且当编译器没有收拾我的懈怠时感到惊讶。
答案 0 :(得分:5)
我在公共汽车上,所以,简短的回答。
t的类型推断需要知道参数中委托类型的形式参数类型。
将方法组转换为委托类型会执行重载解析,就像使用目标委托的形式参数类型的参数调用方法组一样。
但这些类型是我们试图推断出来的!
这是循环推理,因此类型推断拒绝它。方法组转换要求从其他参数中推导出形式参数类型。
你没有其他论据。
因此推断失败。
该组只包含一种方法无关紧要。如果向组中添加更多方法导致推断失败,那将是奇怪的。通过重载解析来解决一组重载的规则是明智的,这需要知道参数。你不能仅仅因为一个方法组恰好是一个单例而向后运行推论。
请参阅我的msdn博客上的类型推断标记,以获取有关此主题的更长篇文章。