<ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>


      一、前言

      上一篇 <https://www.cnblogs.com/snailblog/p/11521043.html>
      我們對(duì)表達(dá)式樹有了初步的認(rèn)識(shí),這里我們將對(duì)表達(dá)式樹進(jìn)行遍歷,只有弄清楚了他的運(yùn)行原理,我們才可以對(duì)他進(jìn)行定制化修改。

      表達(dá)式系列目錄

      C# 表達(dá)式樹講解(一) <https://www.cnblogs.com/snailblog/p/11521043.html>

      C# 表達(dá)式樹遍歷(二)

      ?C# 表達(dá)式樹分頁(yè)擴(kuò)展(三) <https://www.cnblogs.com/snailblog/p/11521359.html>

      C# 表達(dá)式樹Lambda擴(kuò)展(四) <https://www.cnblogs.com/snailblog/p/11525118.html>

      二、表達(dá)式樹的遍歷

      要查看表達(dá)式樹的遍歷,肯定不能直接用.Net Framework封裝的方法,因?yàn)?Net
      Framework框架是閉源的,除了看中間語(yǔ)言(IL)去查看。我們就用ExpressionVisitor類查看一下他的運(yùn)行原理,看了下ExpressionVisitor類,里面都是對(duì)各個(gè)表達(dá)式的訪問,而且都是虛擬函數(shù),我們可以對(duì)他進(jìn)行override。


      ExpressionVisitor類里面都是對(duì)各個(gè)類型的表達(dá)式進(jìn)行訪問,為了更好的理解里面的訪問順序,蝸牛把里面的虛函數(shù)都o(jì)verride了一遍,然后跟蹤里面的執(zhí)行順序。【傻眼了,35個(gè)虛函數(shù)需要override,內(nèi)心是很拒絕的,vs2019有沒有重寫父類虛函數(shù)的快捷鍵?。。。。。。?!】

      ExpressionVisitor類相關(guān)介紹:
      https://docs.microsoft.com/zh-cn/dotnet/api/system.linq.expressions.expressionvisitor?view=netframework-4.8

      <https://docs.microsoft.com/zh-cn/dotnet/api/system.linq.expressions.expressionvisitor?view=netframework-4.8>

      2.1、ExpressionVisitor類的跟蹤

      為了不改變ExpressionVisitor類原來(lái)的訪問,創(chuàng)建的SnailExpressionVisitor.cs 文件只在重寫方法里面添加日志打印。

      代碼如下:
      public class SnailExpressionVisitor : ExpressionVisitor { public override
      Expression Visit(Expression node) { Console.WriteLine($"訪問了
      Visit,內(nèi)容:{node.ToString()}"); return base.Visit(node); } protected override
      CatchBlock VisitCatchBlock(CatchBlock node) { Console.WriteLine($"訪問了
      VisitCatchBlock,內(nèi)容:{node.ToString()}"); return base.VisitCatchBlock(node); }
      protected override ElementInit VisitElementInit(ElementInit node) {
      Console.WriteLine($"訪問了 VisitElementInit,內(nèi)容:{node.ToString()}"); return base
      .VisitElementInit(node); }protected override LabelTarget
      VisitLabelTarget(LabelTarget node) { Console.WriteLine($"訪問了
      VisitLabelTarget,內(nèi)容:{node.ToString()}"); return base.VisitLabelTarget(node); }
      protected override MemberAssignment VisitMemberAssignment(MemberAssignment
      node) { Console.WriteLine($"訪問了 VisitMemberAssignment,內(nèi)容:{node.ToString()}");
      return base.VisitMemberAssignment(node); } protected override MemberBinding
      VisitMemberBinding(MemberBinding node) { Console.WriteLine($"訪問了
      VisitMemberBinding,內(nèi)容:{node.ToString()}"); return base
      .VisitMemberBinding(node); }protected override MemberListBinding
      VisitMemberListBinding(MemberListBinding node) { Console.WriteLine($"訪問了
      VisitMemberListBinding,內(nèi)容:{node.ToString()}"); return base
      .VisitMemberListBinding(node); }protected override MemberMemberBinding
      VisitMemberMemberBinding(MemberMemberBinding node) { Console.WriteLine($"訪問了
      VisitMemberMemberBinding,內(nèi)容:{node.ToString()}"); return base
      .VisitMemberMemberBinding(node); }protected override SwitchCase
      VisitSwitchCase(SwitchCase node) { Console.WriteLine($"訪問了
      VisitSwitchCase,內(nèi)容:{node.ToString()}"); return base.VisitSwitchCase(node); }
      protected override Expression VisitBinary(BinaryExpression node) {
      Console.WriteLine($"訪問了 VisitBinary,內(nèi)容:{node.ToString()}"); return base
      .VisitBinary(node); }protected override Expression VisitBlock(BlockExpression
      node) { Console.WriteLine($"訪問了 VisitBlock,內(nèi)容:{node.ToString()}"); return base
      .VisitBlock(node); }protected override Expression
      VisitConditional(ConditionalExpression node) { Console.WriteLine($"訪問了
      VisitConditional,內(nèi)容:{node.ToString()}"); return base.VisitConditional(node); }
      protected override Expression VisitConstant(ConstantExpression node) {
      Console.WriteLine($"訪問了 VisitConstant,內(nèi)容:{node.ToString()}"); return base
      .VisitConstant(node); }protected override Expression
      VisitDebugInfo(DebugInfoExpression node) { Console.WriteLine($"訪問了
      VisitDebugInfo,內(nèi)容:{node.ToString()}"); return base.VisitDebugInfo(node); }
      protected override Expression VisitDefault(DefaultExpression node) {
      Console.WriteLine($"訪問了 VisitDefault,內(nèi)容:{node.ToString()}"); return base
      .VisitDefault(node); }protected override Expression
      VisitDynamic(DynamicExpression node) { Console.WriteLine($"訪問了
      VisitDynamic,內(nèi)容:{node.ToString()}"); return base.VisitDynamic(node); } protected
      override Expression VisitExtension(Expression node) { Console.WriteLine($"訪問了
      VisitExtension,內(nèi)容:{node.ToString()}"); return base.VisitExtension(node); }
      protected override Expression VisitGoto(GotoExpression node) {
      Console.WriteLine($"訪問了 VisitGoto,內(nèi)容:{node.ToString()}"); return base
      .VisitGoto(node); }protected override Expression VisitIndex(IndexExpression
      node) { Console.WriteLine($"訪問了 VisitIndex,內(nèi)容:{node.ToString()}"); return base
      .VisitIndex(node); }protected override Expression
      VisitInvocation(InvocationExpression node) { Console.WriteLine($"訪問了
      VisitInvocation,內(nèi)容:{node.ToString()}"); return base.VisitInvocation(node); }
      protected override Expression VisitLabel(LabelExpression node) {
      Console.WriteLine($"訪問了 VisitLabel,內(nèi)容:{node.ToString()}"); return base
      .VisitLabel(node); }protected override Expression VisitLambda<T>(Expression<T>
      node) { Console.WriteLine($"訪問了 VisitLambda,內(nèi)容:{node.ToString()}"); return base
      .VisitLambda(node); }protected override Expression
      VisitListInit(ListInitExpression node) { Console.WriteLine($"訪問了
      VisitListInit,內(nèi)容:{node.ToString()}"); return base.VisitListInit(node); }
      protected override Expression VisitLoop(LoopExpression node) {
      Console.WriteLine($"訪問了 VisitLoop,內(nèi)容:{node.ToString()}"); return base
      .VisitLoop(node); }protected override Expression VisitMember(MemberExpression
      node) { Console.WriteLine($"訪問了 VisitMember,內(nèi)容:{node.ToString()}"); return base
      .VisitMember(node); }protected override Expression
      VisitMemberInit(MemberInitExpression node) { Console.WriteLine($"訪問了
      VisitMemberInit,內(nèi)容:{node.ToString()}"); return base.VisitMemberInit(node); }
      protected override Expression VisitMethodCall(MethodCallExpression node) {
      Console.WriteLine($"訪問了 VisitMethodCall,內(nèi)容:{node.ToString()}"); return base
      .VisitMethodCall(node); }protected override Expression VisitNew(NewExpression
      node) { Console.WriteLine($"訪問了 VisitNew,內(nèi)容:{node.ToString()}"); return base
      .VisitNew(node); }protected override Expression
      VisitNewArray(NewArrayExpression node) { Console.WriteLine($"訪問了
      VisitNewArray,內(nèi)容:{node.ToString()}"); return base.VisitNewArray(node); }
      protected override Expression VisitParameter(ParameterExpression node) {
      Console.WriteLine($"訪問了 VisitParameter,內(nèi)容:{node.ToString()}"); return base
      .VisitParameter(node); }protected override Expression
      VisitRuntimeVariables(RuntimeVariablesExpression node) { Console.WriteLine($"
      訪問了 VisitRuntimeVariables,內(nèi)容:{node.ToString()}"); return base
      .VisitRuntimeVariables(node); }protected override Expression
      VisitSwitch(SwitchExpression node) { Console.WriteLine($"訪問了
      VisitSwitch,內(nèi)容:{node.ToString()}"); return base.VisitSwitch(node); } protected
      override Expression VisitTry(TryExpression node) { Console.WriteLine($"訪問了
      VisitTry,內(nèi)容:{node.ToString()}"); return base.VisitTry(node); } protected
      override Expression VisitTypeBinary(TypeBinaryExpression node) {
      Console.WriteLine($"訪問了 VisitTypeBinary,內(nèi)容:{node.ToString()}"); return base
      .VisitTypeBinary(node); }protected override Expression
      VisitUnary(UnaryExpression node) { Console.WriteLine($"訪問了
      VisitUnary,內(nèi)容:{node.ToString()}"); return base.VisitUnary(node); } }
      調(diào)用方法:
      Expression<Func<int, int, bool>> fun = (x, y) => x - y > 5; var treeModifier =
      new SnailExpressionVisitor(); Expression modifiedExpr = treeModifier.Visit(fun);
      運(yùn)行結(jié)果:


      <https://img2018.cnblogs.com/blog/1764554/201909/1764554-20190915102305051-1533802902.png>

      從打印的日志里面可以看出,

      1、每次訪問表達(dá)式類時(shí),都會(huì)先去調(diào)用Visit函數(shù),估計(jì)他是在Visit里面判定表達(dá)式類,然后在根據(jù)表達(dá)式類的類型,調(diào)用訪問改表達(dá)式的函數(shù)


      2、對(duì)Lambda表達(dá)式類,是先訪問的是Expression<T>。Expression<T>是不是很熟悉,上一章說(shuō)過(guò)他的作用是將強(qiáng)類型Lambda表達(dá)式表示為表達(dá)式樹形式的數(shù)據(jù)結(jié)構(gòu),解析成功之后才對(duì)表達(dá)式的訪問

      3、對(duì)于表達(dá)式先解析的是左邊,左邊的內(nèi)容解析完了之后在解析右邊,如(x-y)>5,解析的順序是:x-y=>x=>y=>5

      2.2、修改表達(dá)式樹

      既然我們弄清楚了表達(dá)式樹的訪問,現(xiàn)在我們就可以對(duì)他進(jìn)行編輯修改了。

      上面我們判斷的是x-y>5,現(xiàn)在我們規(guī)定,將“-”改成“+”,“>”改成“>=”

      對(duì)VisitBinary方法修改代碼如下:
      protected override Expression VisitBinary(BinaryExpression node) {
      Console.WriteLine($"訪問了 VisitBinary,內(nèi)容:{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,更改之后的內(nèi)容:{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,更改之后的內(nèi)容:{result.ToString()}");
      return result; } else { return base.VisitBinary(node); } }
      調(diào)用方法:
      Expression<Func<int, int, bool>> fun = (x, y) => x - y > 5; var treeModifier =
      new SnailExpressionVisitor(); Expression modifiedExpr =
      treeModifier.Visit(fun); Console.WriteLine($"
      Lambda的轉(zhuǎn)換最后結(jié)果:{modifiedExpr.ToString()}");
      運(yùn)行結(jié)果如下


      <https://img2018.cnblogs.com/blog/1764554/201909/1764554-20190915102306070-1298442000.png>

      三、總結(jié)


      對(duì)表達(dá)樹的講解已經(jīng)完成了,但是說(shuō)了這么久,對(duì)真實(shí)的開發(fā)有什么作用呢?后面我將利用Lambda表達(dá)式寫一個(gè)對(duì)現(xiàn)有數(shù)據(jù)分頁(yè)的公共方法,同時(shí)在對(duì)Dapper的擴(kuò)展也會(huì)用到相關(guān)知識(shí)點(diǎn),大家拭目以待吧……

      友情鏈接
      ioDraw流程圖
      API參考文檔
      OK工具箱
      云服務(wù)器優(yōu)惠
      阿里云優(yōu)惠券
      騰訊云優(yōu)惠券
      京東云優(yōu)惠券
      站點(diǎn)信息
      問題反饋
      郵箱:[email protected]
      QQ群:637538335
      關(guān)注微信

        <ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>
          日漫无羞遮肉动漫网盘资源 | 插插插男男网站入口 | 动漫美女被吸乳羞羞 | 久久久久久99精品久久久 | 逼逼逼逼逼逼逼 | AV周晓琳一区二区三区 | 一区二区不卡 | 男女激情国产 | 99久久九九 | 国产天堂网 |