一、前言


          一直想寫(xiě)一篇Dpper的定制化擴(kuò)展的文章,但是里面會(huì)設(shè)計(jì)到對(duì)Lambda表達(dá)式的解析,而解析Lambda表達(dá)式,就必須要知道表達(dá)式樹(shù)的相關(guān)知識(shí)點(diǎn)。我希望能通過(guò)對(duì)各個(gè)模塊的知識(shí)點(diǎn)或者運(yùn)用能夠多一點(diǎn)的講解,能夠幫助到園友了解得更多。雖然講解得不全面,如果能成為打開(kāi)這塊的一把鑰匙,也是蝸牛比較欣慰的。

          表達(dá)式系列目錄

          C# 表達(dá)式樹(shù)講解(一)

          C# 表達(dá)式樹(shù)遍歷(二) <https://www.cnblogs.com/snailblog/p/11521335.html>

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

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

          二、表達(dá)樹(shù)理解


          表達(dá)式樹(shù)以樹(shù)形數(shù)據(jù)結(jié)構(gòu)表示代碼,其中每一個(gè)節(jié)點(diǎn)都是一種表達(dá)式,它將我們?cè)瓉?lái)可以直接由代碼編寫(xiě)的邏輯以表達(dá)式的方式存儲(chǔ)在樹(shù)狀的結(jié)構(gòu)里,從而可以在運(yùn)行時(shí)去解析這個(gè)樹(shù),然后執(zhí)行,實(shí)現(xiàn)動(dòng)態(tài)的編輯和執(zhí)行代碼。在.Net
          里面的Linq to SQL就是對(duì)表達(dá)式樹(shù)的解析。


          這里先講解下表達(dá)式和表達(dá)式樹(shù),表達(dá)式相信大家都知道,比如x+5或者5,都可以算是表達(dá)式,而表達(dá)式樹(shù)里面的樹(shù)指的二叉樹(shù),也就是表達(dá)式的集合,C#中的Expression類就是表達(dá)式類。對(duì)于一棵表達(dá)式樹(shù),其葉子節(jié)點(diǎn)都是參數(shù)或者常數(shù),非葉子節(jié)點(diǎn)都是運(yùn)算符或者控制符。

          2.1、表達(dá)式的創(chuàng)建

          Lambda表達(dá)式方法:
          Expression<Func<int, int,bool>> fun = (x, y) => x < y
          這種方法創(chuàng)建出的表達(dá)式根節(jié)點(diǎn)類型為ExpressionType.Lambda,Type類型為返回值類型typeof(bool)

          組裝法(通過(guò) API 創(chuàng)建表達(dá)式樹(shù)):
          ParameterExpression numParam = Expression.Parameter(typeof(int), "num");
          ConstantExpression five = Expression.Constant(5,typeof(int)); BinaryExpression
          numLessThanFive = Expression.LessThan(numParam, five); Expression<Func<int, bool
          >> lambda1 = Expression.Lambda<Func<int, bool>>( numLessThanFive, new
          ParameterExpression[] { numParam });

          我們先創(chuàng)建了兩個(gè)參數(shù)表達(dá)式num和5,然后用LessThan組裝在一起,最終的表達(dá)式為“num<5”,expr的節(jié)點(diǎn)類型為L(zhǎng)essThan,Type類型為typeof(bool)

          我們先看看表達(dá)式樹(shù)里面的構(gòu)造


          首先Expression<TDelegate>的功能是將強(qiáng)類型Lambda表達(dá)式表示為表達(dá)式樹(shù)形式的數(shù)據(jù)結(jié)構(gòu),他的父類是LambdaExpression,比較他們代碼可知,Lambda表達(dá)式的主體,名稱和參數(shù)全部保存在LambdaExpression里面。

          Expression<TDelegate>與LambdaExpression代碼截圖:


          <https://img2018.cnblogs.com/blog/1764554/201909/1764554-20190915071754137-2086334705.png>


          <https://img2018.cnblogs.com/blog/1764554/201909/1764554-20190915071755051-290137207.png>

          LambdaExpression里面的Body就是我們的表達(dá)式。

          C#表達(dá)式給我們提供了豐富的表達(dá)式類,進(jìn)入到LambdaExpression類里面


          <https://img2018.cnblogs.com/blog/1764554/201909/1764554-20190915071756183-938814028.png>

          方法返回類型以“Expression”結(jié)尾的,基本上都是一個(gè)表達(dá)式類。

          每個(gè)表達(dá)式代表的定義和創(chuàng)建方法,可以參照微軟官方文檔
          https://docs.microsoft.com/zh-cn/dotnet/api/system.linq.expressions.binaryexpression?view=netframework-4.8

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

          下面是平常使用最多的表達(dá)式

          ConstantExpression:常量表達(dá)式

          ParameterExpression:參數(shù)表達(dá)式

          UnaryExpression:一元運(yùn)算符表達(dá)式

          BinaryExpression:二元運(yùn)算符表達(dá)式

          TypeBinaryExpression:is運(yùn)算符表達(dá)式

          ConditionalExpression:條件表達(dá)式

          MemberExpression:訪問(wèn)字段或?qū)傩员磉_(dá)式

          MethodCallExpression:調(diào)用成員函數(shù)表達(dá)式

          Expression<TDelegate>:委托表達(dá)式

          2.2、表達(dá)式的解析

          表達(dá)式樹(shù)解析


          通過(guò)LambdaExpression類我們可以知道,表達(dá)式樹(shù)包含:參數(shù)[Parameters],表達(dá)式樹(shù)類型[NodeType],表達(dá)式[Body],返回類型[ReturnType],Lambda表達(dá)式的委托[Compile]以及Lambda表達(dá)式名稱[name],如圖所示:


          <https://img2018.cnblogs.com/blog/1764554/201909/1764554-20190915071757461-354039163.png>

          表達(dá)式解析:

          所有的表達(dá)式都包含:左節(jié)點(diǎn)【Left】,右節(jié)點(diǎn)【Right】,類型【NodeType】,不同的表達(dá)式還會(huì)有其他屬性,這里的左右節(jié)點(diǎn)依舊是表達(dá)式。

          下圖是BinaryExpression表達(dá)式截圖


          <https://img2018.cnblogs.com/blog/1764554/201909/1764554-20190915071758295-213967368.png>

          表達(dá)式樹(shù)和表達(dá)式里面的類型NodeType是一個(gè)枚舉,一共有85個(gè)類型,有興趣的朋友可以去了解下。

          常用的類型如下:

          ExpressionType.And:C#中類似于&

          ExpressionType.AndAlso:C#中類似于&&

          ExpressionType.Or:C#中類似于|

          ExpressionType.OrElse:C#中類似于||

          ExpressionType.Equal:C#中類似于==

          ExpressionType.NotEqual:C#中類似于!=

          ExpressionType.GreaterThan:C#中類似于>

          ExpressionType.GreaterThanOrEqual:C#中類似于>=

          ExpressionType.LessThan:C#中類似于<

          ExpressionType.LessThanOrEqual:C#中類似于<=

          ExpressionType.Add:C#中類似于+

          ExpressionType.AddChecked:C#中類似于+

          ExpressionType.Subtract:C#中類似于-

          ExpressionType.SubtractChecked:C#中類似于-

          ExpressionType.Divide:C#中類似于/

          ExpressionType.Multiply:C#中類似于*

          ExpressionType.MultiplyChecked:C#中類似于*

          2.3、編譯表達(dá)式樹(shù)


          在表達(dá)式創(chuàng)建那,我們組合創(chuàng)建了一個(gè)Lambda表達(dá)式,那么應(yīng)該怎么使用它呢?在“表達(dá)式的解析”里面,LambdaExpression類和Expression<TDelegate>類都有一個(gè)Compile的方法,學(xué)名是Lambda表達(dá)式的委托,其實(shí)就是Lambda表達(dá)式編譯函數(shù)的委托,所以我們只需要調(diào)用他,得到的結(jié)果就是一個(gè)函數(shù)方法。

          代碼修改如下:


          ParameterExpression numParam = Expression.Parameter(typeof(int), "num");
          ConstantExpression five = Expression.Constant(5,typeof(int)); BinaryExpression
          numLessThanFive = Expression.LessThan(numParam, five); Expression<Func<int, bool
          >> lambda1 = Expression.Lambda<Func<int, bool>>( numLessThanFive, new
          ParameterExpression[] { numParam }); Console.WriteLine($"
          Lambda的內(nèi)容:{lambda1.ToString()}"); //表達(dá)式的編譯 var func = lambda1.Compile();
          Console.WriteLine($"Lambda的運(yùn)行結(jié)果:{func(6)}");
          運(yùn)行結(jié)果


          <https://img2018.cnblogs.com/blog/1764554/201909/1764554-20190915071759024-1214255219.png>

          三、總結(jié)

          這里我們對(duì)表達(dá)式做了基本的講解,相信大家對(duì)Lambda表達(dá)式有了初步的了解,下面我們將繼續(xù)講解對(duì)一個(gè)表達(dá)式樹(shù)的遍歷。

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

                口爆人妻 | 青青精品视频在线观看 | 日韩性事 | 少妇的呻吟k8 | 最新国产亚洲免费在线视频 |