C# 表达式树遍历(二)

时间:2021-12-22 01:56:20

标签:

一、前言

上一篇我们对表达式树有了初步的认识,这里我们将对表达式树进行遍历,只有弄清楚了他的运行原理,我们才可以对他进行定制化修改。

表达式系列目录

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

2.1、ExpressionVisitor类的跟踪

为了不改变ExpressionVisitor类原来的访问,创建的SnailExpressionVisitor.cs 文件只在重写方法里面添加日志打印。

代码如下:

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<T>(Expression<T> node) { Console.WriteLine($"访问了 VisitLambda,内容:{node.ToString()}"); return base.VisitLambda(node); } protected override Expression VisitListInit(ListInitExpression node) { Console.WriteLine($"访问了 VisitListInit,内容:{node.ToString()}"); return base.VisitListInit(node); } protected override Expression VisitLoop(LoopExpression node) { Console.WriteLine($"访问了 VisitLoop,内容:{node.ToString()}"); return base.VisitLoop(node); } protected override Expression VisitMember(MemberExpression node) { Console.WriteLine($"访问了 VisitMember,内容:{node.ToString()}"); return base.VisitMember(node); } protected override Expression VisitMemberInit(MemberInitExpression node) { Console.WriteLine($"访问了 VisitMemberInit,内容:{node.ToString()}"); return base.VisitMemberInit(node); } protected override Expression VisitMethodCall(MethodCallExpression node) { Console.WriteLine($"访问了 VisitMethodCall,内容:{node.ToString()}"); return base.VisitMethodCall(node); } protected override Expression VisitNew(NewExpression node) { Console.WriteLine($"访问了 VisitNew,内容:{node.ToString()}"); return base.VisitNew(node); } protected override Expression VisitNewArray(NewArrayExpression node) { Console.WriteLine($"访问了 VisitNewArray,内容:{node.ToString()}"); return base.VisitNewArray(node); } protected override Expression VisitParameter(ParameterExpression node) { Console.WriteLine($"访问了 VisitParameter,内容:{node.ToString()}"); return base.VisitParameter(node); } protected override Expression VisitRuntimeVariables(RuntimeVariablesExpression node) { Console.WriteLine($"访问了 VisitRuntimeVariables,内容:{node.ToString()}"); return base.VisitRuntimeVariables(node); } protected override Expression VisitSwitch(SwitchExpression node) { Console.WriteLine($"访问了 VisitSwitch,内容:{node.ToString()}"); return base.VisitSwitch(node); } protected override Expression VisitTry(TryExpression node) { Console.WriteLine($"访问了 VisitTry,内容:{node.ToString()}"); return base.VisitTry(node); } protected override Expression VisitTypeBinary(TypeBinaryExpression node) { Console.WriteLine($"访问了 VisitTypeBinary,内容:{node.ToString()}"); return base.VisitTypeBinary(node); } protected override Expression VisitUnary(UnaryExpression node) { Console.WriteLine($"访问了 VisitUnary,内容:{node.ToString()}"); return base.VisitUnary(node); } }

调用方法: