在运行时构建表达式树时,没有代码 发射。这是一种在运行时表示.NET代码的方法......
好的...
现在让我说我有这段代码:
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);
Func<string, bool> runnable = lambda.Compile();
这段代码不在IL?当然会! (也许最后一行在编译之前不会发出代码......但我认为第一行会发出代码!)
那么我在这里储蓄了什么?
好的,所以前5行确实发出了代码,而最后一行没有......大不了。
我缺少什么?你能让我看看整个画面吗?
答案 0 :(得分:1)
使用表达式树,您可以构建一些代码的描述,而不是代码本身。 表达式树不应该用于编写“不应该在编译时编译”的常规代码。它们应该用于更动态的场景中。
您显示的表达式树将编译为:s.Length < 5
,并使用runnable
调用bool isStringSmallerThan5 = runnable("MyString")
。
表达式树的整体思想是它们描述了一些代码并且可以在运行时编译。这意味着您可以执行以下操作:
BinaryExpression comparison = null;
if (lessThen)
{
comparison = Expression.LessThan(stringLength, five);
}
else
{
comparison = Expression.GreaterThan(stringLength, five);
}
现在您可以在运行时更改代码的行为!
表达式树的最大用途是它们可以由提供者解释。例如,Linq To Entities使用表达式树并将它们编译为可以对数据库运行的SQL代码。 LinqToXml是您可以使用表达式树做的另一个例子。
这是一个很好的blog post,可以帮助您入门。
答案 1 :(得分:0)
当您在方法中接收表达式树时,表达式树很有用,因为它们使您能够更复杂地使用表达式内容。如果在方法中收到谓词,则可以针对目标运行谓词并检查结果。如果您收到表示表达式树的表达式树,则可以对其进行解析并对其执行一些有用的操作。一个例子是LINQ,它利用了这么多地方,但在“Where”方法中的一个。捕获表达式树而不是IL使得转换为SQL相对简单,而不是仅仅执行完整的“选择”并针对具体化结果运行谓词。