C#编译器用于解析lambda表达式中的类型的规则是什么?
参考
Why can’t an anonymous method be assigned to var?,我知道C#不支持以下内容:
var func = (x,y) => Math.Log(x) + Math.Log(y); 但是,我可以创建一个方法,Func的形式: public static Func<T,T,T> Func<T>(Func<T,T> f) => f; 然后做: var func = Func<double>((x,y) => Math.Log(x) + Math.Log(y)); 那将编译得很好.但是,对于参数和返回值具有不同类型的lambda,事情变得奇怪.例如,如果我有一个方法: public static Func<T1,T2,T3> Func<T1,T3>(Func<T1,T3> f) => f; 我可以这样做: var func = Func((double x,double y) => $"{x + y}"); 那也将编译.所以C#编译器似乎能够推断出lambda的返回类型.但是,以下内容将无法编译: var func = Func((x,y) => Math.Log(x) + Math.Log(y)); 因为编译器似乎无法从它们在体内使用的方式推断出x和y的类型. 所以,我的问题是:关于lambda表达式类型推断的明确规则是什么;编译器将推断出什么,不会推断出什么? 解决方法
最终规则在规范中.如果您想查看实现,可以在Roslyn源代码中轻松找到它;我非常评价它,期待会有问题.请注意,特别是从第110行开始的评论与您的??问题相关;如果您想深入了解lambda类型推断是如何工作的,请仔细研究这一点. https://github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/MethodTypeInference.cs 考虑在调试模式下自己编译编译器;然后,您可以在断点处使用Dump方法来描述类型推理引擎的状态.我使用它来促进更快速的调试,并考虑扩展算法. (其中一些仍然在代码中,注释掉了.)
这是一个过于宽泛的问题,无法明确回答.但是关于你问题中的例子的基本动作是: >类型参数的界限是从与形式参数类型匹配的普通参数推断出来的. 我录制了一段视频 – 十年前现在 – 一步一步地解释所有这些,但显然已经不再是在MSDN上了.我很烦. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |