编译表达树误解了吗?

我有这个表达式:

Expression<Func> f = s => s.Length < 5; 

在此处输入图像描述

 ParameterExpression p = Expression.Parameter (typeof (string), "s"); MemberExpression stringLength = Expression.Property (p, "Length"); ConstantExpression five = Expression.Constant (5); BinaryExpression comparison = Expression.LessThan (stringLength, five); Expression<Func> lambda= Expression.Lambda<Func> (comparison, p); 

//让:测试

 Func runnable = lambda.Compile(); Console.WriteLine (runnable ("kangaroo")); // False Console.WriteLine (runnable ("dog")); //True 

我想问一下.Compile()

什么编译? 第一次执行与后期执行之间的区别是什么?

编译应该是一次发生的事情,而不是以后再发生….

什么/它对我有什么帮助?

在运行时构建表达式树时,不会发出任何代码。 这是一种在运行时表示.NET代码的方法。

在表达式树上调用.Compile方法后,会发出实际的IL代码,将此表达式树转换为可在运行时调用的委托( Func )。 因此,表达式树表示的代码只有在编译后才能执行。

调用编译是一项昂贵的操作。 基本上你应该调用它一次,然后缓存你​​可以用来多次调用代码的结果委托。

Expression>只是表达式的表示,不能执行 。 调用Compile()为您提供一个已编译的委托,一段您可以调用的代码。 本质上,您的程序在运行时编写一个小代码片段,然后将其称为编译器处理它。 这是你的代码的最后两行:正如你所看到的,编译的代码片段可以分析你传入的字符串的长度 – 当长度小于5时,你得到一个True ; 当它是五个或更多,你得到一个False

首次执行编译片段时会发生什么情况取决于平台,使用.NET平台的程序员不应该检测到这种情况。

Compile()接受表达式树(它是某些逻辑的数据表示)并将其转换为IL,然后可以直接作为委托执行。

第一次执行和后续执行之间的唯一区别是Compile()不会触发从IL到本机处理器代码的JIT编译。 这可能发生在第一次执行时。