什么是C#编译器使用的lambda表达式解析类型的规则? [英] What are the rules the C# compiler uses to resolve types in a lambda expression?

查看:126
本文介绍了什么是C#编译器使用的lambda表达式解析类型的规则?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

参照为什么不能匿名方法被分配到VAR ,据我了解,下面是不是在C#支持:

  VAR FUNC =(X,Y)=>将Math.log(X)+将Math.log(Y); 



不过,我可以创建一个方法,函数功能的格式为:

 公共静态Func键< T,T,T> FUNC< T>(FUNC< T,T,T&F)的温度= GT; F; 



然后执行:

  VAR func =函数<双>((X,Y)=>将Math.log(X)+将Math.log(Y)); 

这将编译就好了。然而,对于不同类型的参数和返回值的lambda表达式,事情就变得奇怪。举例来说,如果我有一个方法:

 公共静态Func键< T1,T2,T3> FUNC&所述的T1,T2,T3>(FUNC&下; T1,T2,T3和F)的温度= GT; F; 



我可以为例子做的:

  VAR func =函数((双X,双Y)=> ${X + Y}); 

和太会编。因此,C#编译器似乎能够推断出返回类型的lambda。但是,以下不会编译:

  VAR func =函数((X,Y)=>将Math.log( X)+将Math.log(Y)); 



编译器似乎是不能够推断出类型第X 从它们在体内使用的方式。



所以,我的问题:什么是对lambda表达式类型推断的明确规则;会出现什么编译器推断出,哪些不是吗?


解决方案

什么是对lambda表达式类型推断的明确规则;




明确的规则是在规范中。如果你想看看的实施的,你可以很容易找到它足够的罗斯林来源;我评论它非常沉重,预计会有问题。请注意,特别是围绕110线开始评论是有关你的问题;如果你想要的拉姆达类型推断是如何工作的深刻理解仔细研究这一点。



https://github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution /MethodTypeInference.cs



考虑编译,编译器自己在调试模式;那么你可以使用导出方法的断点,因为它不用来形容类型推理引擎的状态。考虑扩展算法,当我用这个方便更快速的调试和。 (其中一些仍然在代码中,注释掉。)




会出现什么编译器推断,什么不是吗?




这是过于宽泛的问题回答的明确的。但相对于你的问题的例子基本操作是:




  • 边界上的类型参数从形参类型匹配普通参数推断

  • 在lambda 的是推测或已知有他们的返回类型推断

  • 的lambda表达式,所有形式参数类型的前面重复步骤,直到算法不能取得进展,或演绎一对矛盾



我录的视频 - 十年前,现在 - 解释所有这一步一步,但显然它是在MSDN不再。我烦恼。


With reference to Why can't an anonymous method be assigned to var?, I understand that the following is not supported in C#:

var func = (x,y) => Math.Log(x) + Math.Log(y);

However, I can create a method, Func of the form:

public static Func<T,T,T> Func<T>(Func<T,T,T> f) => f;

and then do:

var func = Func<double>((x,y) => Math.Log(x) + Math.Log(y));

that will compile just fine. However, for lambdas with different types for the parameters and return value, things get odd. For example, if I have a method:

public static Func<T1,T2,T3> Func<T1,T2,T3>(Func<T1,T2,T3> f) => f;

I can for example do:

var func = Func((double x, double y) => $"{x + y}");

and that too will compile. So the C# compiler seems to be able to infer the return type for a lambda. But, the following won't compile:

var func = Func((x,y) => Math.Log(x) + Math.Log(y));

as the compiler doesn't seem able to infer the types of x and y from the way they are used in the body.

So, my question: what are the definitive rules on type inference of lambda expressions; what will the compiler infer and what won't it?

解决方案

what are the definitive rules on type inference of lambda expressions;

The definitive rules are in the specification. If you want to look at the implementation, you can find it easily enough in the Roslyn sources; I commented it pretty heavily, anticipating that there would be questions. Note that in particular the comment starting around line 110 is relevant to your question; study this carefully if you want a deep understanding of how lambda type inference works.

https://github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/MethodTypeInference.cs

Consider compiling the compiler yourself in debug mode; you can then use the Dump method at breakpoints to describe the state of the type inference engine as it goes. I used this to facilitate more rapid debugging, and when considering extensions to the algorithm. (Some of which are still in the code, commented out.)

what will the compiler infer and what won't it?

That is far too broad a question to answer definitively. But the basic action with respect to the examples in your question is:

  • Bounds on type parameters are inferred from ordinary arguments matched with formal parameter types.
  • Lambdas where all formal parameter types of the lambda are inferred or known have their return types inferred
  • The previous step is repeated until the algorithm fails to make progress or deduces a contradiction.

I recorded a video -- ten years ago now -- explaining all this step by step but apparently it is no longer on MSDN. I am vexed.

这篇关于什么是C#编译器使用的lambda表达式解析类型的规则?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆