C#中为何可传递委托变量给泛型方法,却不能直接传方法?
方法组在泛型方法参数传递中的类型推断问题
先定义以下两个方法:
string Foo<T>(Func<T, string> f) => throw new NotImplementedException(); string Bar(int x) => x.ToString();
在C#中,先将方法赋值给变量再传递给泛型方法可以正常编译:
var f = Bar; Foo(f); // 编译正常
但直接将方法作为参数传递给泛型方法时会失败:
Foo(Bar);
触发的编译错误为:
无法从用法中推断方法“Program.Foo(Func<T, string>)”的类型参数。请尝试显式指定类型参数。
为什么变量赋值时编译器能成功推断类型,而直接作为参数传递时却不行?
补充说明
Eric Lippert在2011年曾给出相关解答:
具体来说,微妙的差异在于:方法组仅根据参数是否匹配来判断是否可转换为委托类型,而不会考虑返回类型是否匹配。Lambda表达式则会同时检查参数和返回类型。
根据C# 12规范中的方法组转换规则,当前这一逻辑仍然适用:
如果使用类型推断,委托的参数类型会作为推断过程中的参数类型,而委托的返回类型不会用于推断。
不过这里存在看似矛盾的情况:从C# 10开始,仅有单个重载的方法组具有自然类型,这意味着编译器可以推断委托类型的返回类型和参数类型,例如:
var read = Console.Read;
既然编译器确实能够将单重载方法组转换为委托,那为何直接传递给泛型方法时不执行该操作?
内容的提问来源于stack exchange,提问作者Thomas Eyde
相关产品推荐
相关产品推荐

