编译表达树误解了吗?
我有这个表达式:
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编译。 这可能发生在第一次执行时。