C# 表达式树遍历(二)
2021-02-03 03:15
标签:base list lock default ice 定制 over expr 执行 上一篇我们对表达式树有了初步的认识,这里我们将对表达式树进行遍历,只有弄清楚了他的运行原理,我们才可以对他进行定制化修改。 表达式系列目录 C# 表达式树讲解(一) C# 表达式树遍历(二) C# 表达式树分页扩展(三) 要查看表达式树的遍历,肯定不能直接用.Net Framework封装的方法,因为.Net Framework框架是闭源的,除了看中间语言(IL)去查看。我们就用ExpressionVisitor类查看一下他的运行原理,看了下ExpressionVisitor类,里面都是对各个表达式的访问,而且都是虚拟函数,我们可以对他进行override。 ExpressionVisitor类里面都是对各个类型的表达式进行访问,为了更好的理解里面的访问顺序,蜗牛把里面的虚函数都override了一遍,然后跟踪里面的执行顺序。【傻眼了,35个虚函数需要override,内心是很拒绝的,vs2019有没有重写父类虚函数的快捷键啊!!!!!!!】 ExpressionVisitor类相关介绍:https://docs.microsoft.com/zh-cn/dotnet/api/system.linq.expressions.expressionvisitor?view=netframework-4.8 为了不改变ExpressionVisitor类原来的访问,创建的SnailExpressionVisitor.cs 文件只在重写方法里面添加日志打印。 代码如下: 调用方法: 运行结果: 从打印的日志里面可以看出, 1、每次访问表达式类时,都会先去调用Visit函数,估计他是在Visit里面判定表达式类,然后在根据表达式类的类型,调用访问改表达式的函数 2、对Lambda表达式类,是先访问的是Expression 3、对于表达式先解析的是左边,左边的内容解析完了之后在解析右边,如(x-y)>5,解析的顺序是:x-y=>x=>y=>5 既然我们弄清楚了表达式树的访问,现在我们就可以对他进行编辑修改了。 上面我们判断的是x-y>5,现在我们规定,将“-”改成“+”,“>”改成“>=” 对VisitBinary方法修改代码如下: 调用方法: 运行结果如下 对表达树的讲解已经完成了,但是说了这么久,对真实的开发有什么作用呢?后面我将利用Lambda表达式写一个对现有数据分页的公共方法,同时在对Dapper的扩展也会用到相关知识点,大家拭目以待吧…… C# 表达式树遍历(二) 标签:base list lock default ice 定制 over expr 执行 原文地址:https://www.cnblogs.com/snailblog/p/11521335.html一、前言
二、表达式树的遍历
2.1、ExpressionVisitor类的跟踪
public class SnailExpressionVisitor : ExpressionVisitor
{
public override Expression Visit(Expression node)
{
Console.WriteLine($"访问了 Visit,内容:{node.ToString()}");
return base.Visit(node);
}
protected override CatchBlock VisitCatchBlock(CatchBlock node)
{
Console.WriteLine($"访问了 VisitCatchBlock,内容:{node.ToString()}");
return base.VisitCatchBlock(node);
}
protected override ElementInit VisitElementInit(ElementInit node)
{
Console.WriteLine($"访问了 VisitElementInit,内容:{node.ToString()}");
return base.VisitElementInit(node);
}
protected override LabelTarget VisitLabelTarget(LabelTarget node)
{
Console.WriteLine($"访问了 VisitLabelTarget,内容:{node.ToString()}");
return base.VisitLabelTarget(node);
}
protected override MemberAssignment VisitMemberAssignment(MemberAssignment node)
{
Console.WriteLine($"访问了 VisitMemberAssignment,内容:{node.ToString()}");
return base.VisitMemberAssignment(node);
}
protected override MemberBinding VisitMemberBinding(MemberBinding node)
{
Console.WriteLine($"访问了 VisitMemberBinding,内容:{node.ToString()}");
return base.VisitMemberBinding(node);
}
protected override MemberListBinding VisitMemberListBinding(MemberListBinding node)
{
Console.WriteLine($"访问了 VisitMemberListBinding,内容:{node.ToString()}");
return base.VisitMemberListBinding(node);
}
protected override MemberMemberBinding VisitMemberMemberBinding(MemberMemberBinding node)
{
Console.WriteLine($"访问了 VisitMemberMemberBinding,内容:{node.ToString()}");
return base.VisitMemberMemberBinding(node);
}
protected override SwitchCase VisitSwitchCase(SwitchCase node)
{
Console.WriteLine($"访问了 VisitSwitchCase,内容:{node.ToString()}");
return base.VisitSwitchCase(node);
}
protected override Expression VisitBinary(BinaryExpression node)
{
Console.WriteLine($"访问了 VisitBinary,内容:{node.ToString()}");
return base.VisitBinary(node);
}
protected override Expression VisitBlock(BlockExpression node)
{
Console.WriteLine($"访问了 VisitBlock,内容:{node.ToString()}");
return base.VisitBlock(node);
}
protected override Expression VisitConditional(ConditionalExpression node)
{
Console.WriteLine($"访问了 VisitConditional,内容:{node.ToString()}");
return base.VisitConditional(node);
}
protected override Expression VisitConstant(ConstantExpression node)
{
Console.WriteLine($"访问了 VisitConstant,内容:{node.ToString()}");
return base.VisitConstant(node);
}
protected override Expression VisitDebugInfo(DebugInfoExpression node)
{
Console.WriteLine($"访问了 VisitDebugInfo,内容:{node.ToString()}");
return base.VisitDebugInfo(node);
}
protected override Expression VisitDefault(DefaultExpression node)
{
Console.WriteLine($"访问了 VisitDefault,内容:{node.ToString()}");
return base.VisitDefault(node);
}
protected override Expression VisitDynamic(DynamicExpression node)
{
Console.WriteLine($"访问了 VisitDynamic,内容:{node.ToString()}");
return base.VisitDynamic(node);
}
protected override Expression VisitExtension(Expression node)
{
Console.WriteLine($"访问了 VisitExtension,内容:{node.ToString()}");
return base.VisitExtension(node);
}
protected override Expression VisitGoto(GotoExpression node)
{
Console.WriteLine($"访问了 VisitGoto,内容:{node.ToString()}");
return base.VisitGoto(node);
}
protected override Expression VisitIndex(IndexExpression node)
{
Console.WriteLine($"访问了 VisitIndex,内容:{node.ToString()}");
return base.VisitIndex(node);
}
protected override Expression VisitInvocation(InvocationExpression node)
{
Console.WriteLine($"访问了 VisitInvocation,内容:{node.ToString()}");
return base.VisitInvocation(node);
}
protected override Expression VisitLabel(LabelExpression node)
{
Console.WriteLine($"访问了 VisitLabel,内容:{node.ToString()}");
return base.VisitLabel(node);
}
protected override Expression VisitLambda
Expression
2.2、修改表达式树
protected override Expression VisitBinary(BinaryExpression node)
{
Console.WriteLine($"访问了 VisitBinary,内容:{node.ToString()}");
if (node.NodeType == ExpressionType.GreaterThan)
{
Expression left = this.Visit(node.Left);
Expression right = this.Visit(node.Right);
var result = Expression.MakeBinary(ExpressionType.GreaterThanOrEqual, left, right, node.IsLiftedToNull, node.Method);
Console.WriteLine($"访问了 VisitBinary,更改之后的内容:{result.ToString()}");
return result;
}
else if (node.NodeType == ExpressionType.Subtract || node.NodeType == ExpressionType.SubtractChecked)
{
Expression left = this.Visit(node.Left);
Expression right = this.Visit(node.Right);
var result = Expression.MakeBinary(ExpressionType.Add, left, right, node.IsLiftedToNull, node.Method);
Console.WriteLine($"访问了 VisitBinary,更改之后的内容:{result.ToString()}");
return result;
}
else
{
return base.VisitBinary(node);
}
}
Expression
三、总结