日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

表达式树练习实践:入门基础

發布時間:2023/12/4 编程问答 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 表达式树练习实践:入门基础 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

什么是表達式樹

來自微軟官方文檔的定義:

表達式樹以樹形數據結構表示代碼。

它能干什么呢?

你可以對表達式樹中的代碼進行編輯和運算。這樣能夠動態修改可執行代碼、在不同數據庫中執行 LINQ 查詢以及創建動態查詢。

好不好玩?

表達式樹還能用于動態語言運行時 (DLR) 以提供動態語言和 .NET Framework 之間的互操作性,同時保證編譯器編寫員能夠發射表達式樹而非 Microsoft 中間語言 (MSIL)。

哪里有應用?

ORM框架、工作流框架等,使用到 Lambda 的代碼。。。動態執行代碼、動態組裝代碼等。

創建表達式樹

創建表達式樹有兩種方式:通過 lambda 表達式、通過 API。

創建表達式樹的意思是,在此之前已經編寫好每個結點,最后使用代碼將所有結點組合起來,生成表達式樹。

示例(通過API創建表達式樹)

```ParameterExpression a = Expression.Parameter(typeof(int), "i");ParameterExpression b = Expression.Parameter(typeof(int), "j");Expression r1 = Expression.Multiply(a, b);ParameterExpression c = Expression.Parameter(typeof(int), "x");ParameterExpression d = Expression.Parameter(typeof(int), "y");Expression r2 = Expression.Multiply(c, d);Expression result = Expression.Add(r1, r2);Expression<Func<int, int, int, int, int>> func = Expression.Lambda<Func<int, int, int, int, int>>(result, a, b, c, d);var com = func.Compile();Console.WriteLine("表達式" + func);Console.WriteLine(com(12, 12, 13, 13));Console.ReadKey();

上面關于表達式樹的代碼很多,以下這一步叫生成/創建表達式樹。

Expression<Func<int, int, int, int, int>> func = Expression.Lambda<Func<int, int, int, int, int>>(result, a, b, c, d);

以下這句叫執行表達式樹

var com = func.Compile();

其它代碼是用于生成表達式樹結點/邏輯。

回歸正題,創建表達式樹的兩種方法。

lambda 創建表達式樹

上面的表達式樹示例,是用于生成

( i * j ) + ( x * y )

但是就這么簡單的操作,要寫這么長,實在不合理。

而通過 lambda ,可以這樣寫

Expression<Func<int, int, int, int, int>> func = (i, j, x, y) => (i * j) + (x * y);

如果使用 lambda 生成表達式樹, lambda 只能使用單行語句,不能使用 if、for等語句。

具體關于 Lambda 的表達式樹,后面其它文章有說明。

通過 API 創建表達式樹

就是這樣

Expression<Func<int, int, int, int, int>> func = Expression.Lambda<Func<int, int, int, int, int>>(result, a, b, c, d);

兩種方式左邊的都是一樣的,區別在于等號右邊。

Expression< TDelegate >

上面示例的最終結果都是生成

Expression<Func<int, int, int, int, int>> func

func 是表達式樹變量。

我們可以了解以下表達式樹具有的方法和屬性。

用于生成表達式樹結點的,是 Expression 類型。

那么,創建的表達式樹 func ,是?Expression<TDelegate>類型。

定義如下

public sealed class Expression<TDelegate> : LambdaExpression

具有方法如下

Compile()將表達式樹描述的 lambda 表達式編譯為可執行代碼,并生成表示 lambda 表達式的委托。
Compile(Boolean)將表達式樹描述的 Lambda 表達式編譯為已解釋或已編譯的代碼,并生成表示該 Lambda 表達式的委托。
Compile(DebugInfoGenerator)將 lambda 編譯到方法定義中。(Inherited from LambdaExpression)
Update(Expression, IEnumerable)創建一個與此表達式類似的新表達式,但使用所提供的子級。如果所有子級都相同,則將返回此表達式。
Accept(ExpressionVisitor)調度到此節點類型的特定 Visit 方法。例如,MethodCallExpression調用 VisitMethodCall。

由于?Expression<TDelegate>?繼承了?LambdaExpression,所以有很多屬性方法也可以用。

CanReduce指示可將節點簡化為更簡單的節點。如果返回 true,則可以調用 Reduce() 以生成簡化形式。
Name獲取 lambda 表達式的名稱。
NodeType返回此 Expression 的節點類型。
Parameters獲取 lambda 表達式的參數。
ReturnType獲取 lambda 表達式的返回類型。
TailCall獲取一個值,該值指示是否將通過尾調用優化來編譯 lambda 表達式。
Type獲取此 Expression 表示的表達式的靜態類型。

好了,以上權當小筆記,備忘,目前先用不上,后面慢慢來使用。

解析/執行表達式樹

創建表達式樹后,就要執行表達式樹。

在此之前,你需要了解 委托 Delegate,Func,Action,以及他們中間的關系。

執行表達式樹是這樣子的

Expression<Func<int, int, int, int, int>> func = Expression.Lambda<Func<int, int, int, int, int>>(result, a, b, c, d);var com = func.Compile();var runRasult = com(12, 12, 13, 13);

func 只是一個表達式樹,我們把表達式樹構建好后,“要將表達式樹轉為代碼”,使用

.Compile()?方法,可以將表達式樹生成一個 委托(例如上面的 com)。

為了簡潔上面使用了 var,實際上是這樣的

Func<int,int,int,int,int> com = func.Compile();

四個參數,一個返回值。

var runRasult = com(12, 12, 13, 13);

C#里有語法糖,對委托可以這樣寫

以后后面都是這樣寫了,能夠縮成一行的代碼,就沒必要寫出兩行。

在 Vs 里面調試和查看表達式樹,可以看這里

https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/concepts/expression-trees/debugging-expression-trees-in-visual-studio

初學者不必糾結于這些,了解一下本文內容,記一下概要信息即可。

總結

以上是生活随笔為你收集整理的表达式树练习实践:入门基础的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。