如何修改表达式目录树
ExpressionVisitor介绍
ExpressionVisitor是微软提供的修改表达式目录树的类,可以继承使用ExpressionVisitor递归解析表达式目录树。
继承封装ExpressionVisitor
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
namespace UpdateExpression
{
/// <summary>
/// 使用ExpressionVisitor肯定要递归解析表达式目录树,因为是不知道深度的一棵树。
/// 它只有一个入口叫Visit
/// 首先检查是什么类型的表达式,然后调用对应的方法A(protected override Expression VisitBinary)
/// 方法A里在调用Visit ---这样就成递归了。
/// 也可以在重写的方法里破坏递归,使其结束递归
/// </summary>
public class OperationVisitor : ExpressionVisitor
{
public Expression Modify(Expression expression)
{
return base.Visit(expression);
}
protected override Expression VisitBinary(BinaryExpression binary)
{
if(binary.NodeType == ExpressionType.Add)
{
var left = binary.Left;//如果用它,只操作了二叉树的第一层
var right = binary.Right;
var left2 = this.Visit(binary.Left);//递归调用
var right2 = this.Visit(binary.Right);//递归调用
return Expression.Subtract(left2,right2);
}
return base.VisitBinary(binary);
}
}
}
使用
OperationVisitor 的作用是将表达式所有的“+”操作全部改为“-”操作。
using System;
using System.Linq.Expressions;
namespace UpdateExpression
{
class Program
{
static void Main(string[] args)
{
Expression<Func<int, int, int>> expression = (m, n) => m * n + 2 + 3;
OperationVisitor operationVisitor = new OperationVisitor();
var cc = operationVisitor.Modify(expression);
}
}
}
扩展
可以只改二叉树某一层的表达式。
做法是,在OperationVisitor中定义一个静态int字段B,重写Visit方法,没调用一个Visit,B就++,这样B就代表二叉树的深度了。这样利用B就可以实现只改某一层的表达式了。