C# 编译表达式树误解?

C# 编译表达式树误解?,c#,.net-4.0,expression-trees,C#,.net 4.0,Expression Trees,我有这样的表达: Expression<Func<string, bool>> f = s => s.Length < 5; 表达式f=s=>s.长度

我有这样的表达:

Expression<Func<string, bool>> f = s => s.Length < 5;
表达式f=s=>s.长度<5;

ParameterExpression p=Expression.Parameter(typeof(string),“s”);
MemberExpression stringLength=Expression.Property(p,“长度”);
恒压五=表达式常数(5);
BinaryExpression比较=Expression.LessThan(stringLength,五);
表达式λ=表达式λ(比较,p);
//测试

Func<string, bool> runnable = lambda.Compile();
Console.WriteLine (runnable ("kangaroo")); // False
Console.WriteLine (runnable ("dog")); //True
Func runnable=lambda.Compile();
Console.WriteLine(可运行(“袋鼠”);//假的
Console.WriteLine(可运行(“狗”))//真的
我想问一下
.Compile()

它编译什么?第一次执行和以后执行之间有什么区别

编译应该只发生一次,以后不会再发生


它对我有何帮助?

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

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

调用Compile是一个昂贵的操作。基本上,您应该调用它一次,然后缓存生成的委托,您可以使用该委托多次调用代码。

表达式只是表达式的表示,无法执行。调用
Compile()。本质上,您的程序在运行时编写一个小代码段,然后调用它,就好像它是由编译器处理的一样。这就是代码的最后两行所做的:如您所见,编译后的代码段可以分析传入的字符串的长度-当长度小于5时,返回一个
True
;当值为5或更多时,您会得到一个
False

编译后的代码段第一次执行时发生的情况取决于平台,使用.NET平台的程序员不应检测到。

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


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

您使用了什么工具生成了这张表达式树图?@Anastasiosyal这是一本书中的内容啊,我明白了,我想我错过了一些伟大的可视化工具。我猜,还有@gcvcdamp。一个有趣的项目可能是支持使用类似的方式将表达式树呈现为图形,尽管我可以看到这样的图形如何快速地处理任何非平凡的表达式。在什么“真实”场景中我会使用它?好啊因此,我在运行时构建表达式,但它要困难得多,并且将包含很多IF(构建它)。。。。你能用我需要动态构建表达式的真实场景进行编辑吗?你说的第一句话是什么意思?您的意思是,第一个示例中的所有5行代码都没有IL代码,而是将直接转换为表达式树?我不相信编译器会进行这样的优化。
Func<string, bool> runnable = lambda.Compile();
Console.WriteLine (runnable ("kangaroo")); // False
Console.WriteLine (runnable ("dog")); //True