五、编译表达式树
Expression<TDelegate> 类型提供了 Compile 方法以将表达式树表示的代码编译成可执行委托。
//创建表达式树
Expression<Func<string, int>> funcExpression = msg => msg.Length;
//表达式树编译成委托
var lambda = funcExpression.Compile();
//调用委托
Console.WriteLine(lambda("Hello, World!"));
//语法简化
Console.WriteLine(funcExpression.Compile()("Hello, World!"));

六、执行表达式树
执行表达式树可能会返回一个值,也可能仅执行一个操作(例如调用方法)。
只能执行表示 lambda 表达式的表达式树。表示 lambda 表达式的表达式树属于 LambdaExpression 或 Expression<TDelegate> 类型。若要执行这些表达式树,需要调用 Compile 方法来创建一个可执行委托,然后调用该委托。
const int n = 1;
const int m = 2;
//待执行的表达式树
BinaryExpression bExpression = Expression.Add(Expression.Constant(n), Expression.Constant(m));
//创建 lambda 表达式
Expression<Func<int>> funcExpression = Expression.Lambda<Func<int>>(bExpression);
//编译 lambda 表达式
Func<int> func = funcExpression.Compile();
//执行 lambda 表达式
Console.WriteLine($"{n} + {m} = {func()}");

七、修改表达式树
该类继承 ExpressionVisitor 类,通过 Visit 方法间接调用 VisitBinary 方法将 != 替换成 ==。基类方法构造类似于传入的表达式树的节点,但这些节点将其子目录树替换为访问器递归生成的表达式树。
internal class Program
{
private static void Main(string[] args)
{
Expression<Func<int, bool>> funcExpression = num => num == 0;
Console.WriteLine($"Source: {funcExpression}");
var visitor = new NotEqualExpressionVisitor();
var expression = visitor.Visit(funcExpression);
Console.WriteLine($"Modify: {expression}");
Console.Read();
}
/// <summary>
/// 不等表达式树访问器
/// </summary>
public class NotEqualExpressionVisitor : ExpressionVisitor
{
public Expression Visit(BinaryExpression node)
{
return VisitBinary(node);
}
protected override Expression VisitBinary(BinaryExpression node)
{
return node.NodeType == ExpressionType.Equal
? Expression.MakeBinary(ExpressionType.NotEqual, node.Left, node.Right) //重新弄个表达式:用 != 代替 ==
: base.VisitBinary(node);
}
}
}










