我有这个表达:
Expression<Func<string, bool>> 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<string, bool>> lambda= Expression.Lambda<Func<string, bool>> (comparison, p);
// let:test
Func<string, bool> runnable = lambda.Compile();
Console.WriteLine (runnable ("kangaroo")); // False
Console.WriteLine (runnable ("dog")); //True
我想问一下.Compile()
它是什么编译的?第一次执行与后期执行之间有什么区别......?
编译应该是一次发生的事情,而不是以后再发生......
什么/它对我有什么帮助?
答案 0 :(得分:10)
在运行时构建表达式树时,不会发出任何代码。这是一种在运行时表示.NET代码的方法。
在表达式树上调用.Compile
方法后,会发出实际的IL代码,以将此表达式树转换为您可以在运行时调用的委托(Func<string, bool>
)。因此,只有在编译之后才能执行此表达式树所代表的代码。
调用编译是一项昂贵的操作。基本上你应该调用它一次,然后缓存你可以用来多次调用代码的结果委托。
答案 1 :(得分:2)
Expression<Func<string,bool>>
只是表达式的表示,不能执行。调用Compile()
会为您提供一个已编译的委托,一段您可以调用的代码。从本质上讲,您的程序在运行时编写一个小代码片段,然后将其称为编译器处理它。这是你的代码的最后两行:正如你所看到的,编译的代码片段可以分析你传入的字符串的长度 - 当长度小于5时,你得到True
;如果它是五个或更多,你得到一个False
。
首次执行编译片段时会发生什么情况取决于平台,使用.NET平台的程序员无法检测到。
答案 2 :(得分:2)
Compile()
获取表达式树(这是某些逻辑的数据表示)并将其转换为IL,然后可以直接作为委托执行。
第一次执行和后续执行之间的唯一区别是Compile()
不会触发从IL到本机处理器代码的JIT编译。 可能在第一次执行时发生。