欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#表達(dá)式樹基礎(chǔ)教程

 更新時(shí)間:2022年01月18日 10:56:38   作者:癡者工良  
這篇文章介紹了C#表達(dá)式樹的基礎(chǔ)教程,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

什么是表達(dá)式樹

來(lái)自微軟官方文檔的定義:

表達(dá)式樹以樹形數(shù)據(jù)結(jié)構(gòu)表示代碼。

它能干什么呢?

你可以對(duì)表達(dá)式樹中的代碼進(jìn)行編輯和運(yùn)算。 這樣能夠動(dòng)態(tài)修改可執(zhí)行代碼、在不同數(shù)據(jù)庫(kù)中執(zhí)行 LINQ 查詢以及創(chuàng)建動(dòng)態(tài)查詢。

好不好玩?

表達(dá)式樹還能用于動(dòng)態(tài)語(yǔ)言運(yùn)行時(shí) (DLR) 以提供動(dòng)態(tài)語(yǔ)言和 .NET Framework 之間的互操作性,同時(shí)保證編譯器編寫員能夠發(fā)射表達(dá)式樹而非 Microsoft 中間語(yǔ)言 (MSIL)。

哪里有應(yīng)用?

ORM框架、工作流框架等,使用到 Lambda 的代碼。。。動(dòng)態(tài)執(zhí)行代碼、動(dòng)態(tài)組裝代碼等。

創(chuàng)建表達(dá)式樹

創(chuàng)建表達(dá)式樹有兩種方式:通過(guò) lambda 表達(dá)式、通過(guò) API。

創(chuàng)建表達(dá)式樹的意思是,在此之前已經(jīng)編寫好每個(gè)結(jié)點(diǎn),最后使用代碼將所有結(jié)點(diǎn)組合起來(lái),生成表達(dá)式樹。

示例(通過(guò)API創(chuàng)建表達(dá)式樹)

            ParameterExpression a = Expression.Parameter(typeof(int), "i");
            ParameterExpression b = Expression.Parameter(typeof(int), "j");

            Expression r1 = Expression.Multiply(a, b);      //乘法運(yùn)行
            ParameterExpression c = Expression.Parameter(typeof(int), "x");
            ParameterExpression d = Expression.Parameter(typeof(int), "y");
            Expression r2 = Expression.Multiply(c, d);      //乘法運(yùn)行

            Expression result = Expression.Add(r1, r2);     //相加
            //以上代碼產(chǎn)生結(jié)點(diǎn)
            //生成表達(dá)式
            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("表達(dá)式" + func);
            Console.WriteLine(com(12, 12, 13, 13));
            Console.ReadKey();

上面關(guān)于表達(dá)式樹的代碼很多,以下這一步叫生成/創(chuàng)建表達(dá)式樹。

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

以下這句叫執(zhí)行表達(dá)式樹

            var com = func.Compile();

其它代碼是用于生成表達(dá)式樹結(jié)點(diǎn)/邏輯。

回歸正題,創(chuàng)建表達(dá)式樹的兩種方法。

lambda 創(chuàng)建表達(dá)式樹

上面的表達(dá)式樹示例,是用于生成

 ( i * j ) + ( x * y ) 

但是就這么簡(jiǎn)單的操作,要寫這么長(zhǎng),實(shí)在不合理。

而通過(guò) lambda ,可以這樣寫

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

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

具體關(guān)于 Lambda 的表達(dá)式樹,后面其它文章有說(shuō)明。

通過(guò) API 創(chuàng)建表達(dá)式樹

就是這樣

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

兩種方式左邊的都是一樣的,區(qū)別在于等號(hào)右邊。

Expression< TDelegate >

上面示例的最終結(jié)果都是生成

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

func 是表達(dá)式樹變量。

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

用于生成表達(dá)式樹結(jié)點(diǎn)的,是 Expression 類型。

那么,創(chuàng)建的表達(dá)式樹 func ,是 Expression<TDelegate> 類型。

定義如下

public sealed class Expression<TDelegate> : LambdaExpression

具有方法如下

定義

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

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

LambdaExpression

Body獲取 lambda 表達(dá)式的主體。
CanReduce指示可將節(jié)點(diǎn)簡(jiǎn)化為更簡(jiǎn)單的節(jié)點(diǎn)。 如果返回 true,則可以調(diào)用 Reduce() 以生成簡(jiǎn)化形式。
Name獲取 lambda 表達(dá)式的名稱。
NodeType返回此 Expression 的節(jié)點(diǎn)類型。
Parameters獲取 lambda 表達(dá)式的參數(shù)。
ReturnType獲取 lambda 表達(dá)式的返回類型。
TailCall獲取一個(gè)值,該值指示是否將通過(guò)尾調(diào)用優(yōu)化來(lái)編譯 lambda 表達(dá)式。
Type獲取此 Expression 表示的表達(dá)式的靜態(tài)類型。

好了,以上權(quán)當(dāng)小筆記,備忘,目前先用不上,后面慢慢來(lái)使用。

解析/執(zhí)行表達(dá)式樹

創(chuàng)建表達(dá)式樹后,就要執(zhí)行表達(dá)式樹。

在此之前,你需要了解 委托 Delegate,F(xiàn)unc,Action,以及他們中間的關(guān)系。

執(zhí)行表達(dá)式樹是這樣子的

            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 只是一個(gè)表達(dá)式樹,我們把表達(dá)式樹構(gòu)建好后,“要將表達(dá)式樹轉(zhuǎn)為代碼”,使用

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

為了簡(jiǎn)潔上面使用了 var,實(shí)際上是這樣的

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

四個(gè)參數(shù),一個(gè)返回值。

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

C#里有語(yǔ)法糖,對(duì)委托可以這樣寫

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

        int runRasult = func.Compile()(12, 12, 13, 13);

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

在 Vs 里面調(diào)試和查看表達(dá)式樹,可以看這里

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

到此這篇關(guān)于C#表達(dá)式樹基礎(chǔ)教程的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • WPF實(shí)現(xiàn)繪制3D圖形的示例代碼

    WPF實(shí)現(xiàn)繪制3D圖形的示例代碼

    WPF的3D功能可以在不編寫任何c#代碼的情況下進(jìn)行繪制,只需要使用xaml即可完成3D圖形的渲染。本文主要講述了WPF-3D中的關(guān)鍵概念, 以及常用到的命中測(cè)試、2d控件如何在3D對(duì)象中進(jìn)行渲染,希望大家有所幫助
    2023-03-03
  • Unity3D實(shí)現(xiàn)模型隨機(jī)切割

    Unity3D實(shí)現(xiàn)模型隨機(jī)切割

    這篇文章主要為大家詳細(xì)介紹了Unity3D實(shí)現(xiàn)模型隨機(jī)切割,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-03-03
  • C#加載嵌入到資源的非托管dll

    C#加載嵌入到資源的非托管dll

    很多朋友遇到過(guò)這樣一個(gè)問題需要加載非win32的非托管dll,糾結(jié)該怎么操作呢,下面通過(guò)代碼給大家介紹下C#加載嵌入到資源的非托管dll的方法,感興趣的朋友一起看看吧
    2021-05-05
  • 獲取wince mac地址與IP地址解決方案

    獲取wince mac地址與IP地址解決方案

    由于需要進(jìn)行身份的驗(yàn)證,需要獲取移動(dòng)終端的MAC地址,于是在網(wǎng)上進(jìn)行搜索整理一番,現(xiàn)在將實(shí)現(xiàn)獲取MAC地址的方法與大家共享
    2012-12-12
  • asp.net中調(diào)用oracle存儲(chǔ)過(guò)程的方法

    asp.net中調(diào)用oracle存儲(chǔ)過(guò)程的方法

    存儲(chǔ)過(guò)程是在大型數(shù)據(jù)庫(kù)系統(tǒng)中,一組為了完成特定功能的SQL 語(yǔ)句集,存儲(chǔ)在數(shù)據(jù)庫(kù)中經(jīng)過(guò)第一次編譯后再次調(diào)用不需要再次編譯,用戶通過(guò)指定存儲(chǔ)過(guò)程的名字并給出參數(shù)來(lái)執(zhí)行它,下面給大家介紹下asp.net中調(diào)用oracle存儲(chǔ)過(guò)程的方法,需要的朋友可以參考下
    2015-08-08
  • C# MVC 微信支付教程系列之掃碼支付代碼實(shí)例

    C# MVC 微信支付教程系列之掃碼支付代碼實(shí)例

    本篇文章主要介紹了C# MVC 微信支付教程系列之掃碼支付,非常具有實(shí)用價(jià)值,需要的朋友可以參考下。
    2016-12-12
  • 使用異步方式調(diào)用同步方法(實(shí)例詳解)

    使用異步方式調(diào)用同步方法(實(shí)例詳解)

    .NET Framework 允許您異步調(diào)用任何方法。為此,應(yīng)定義與您要調(diào)用的方法具有相同簽名的委托;公共語(yǔ)言運(yùn)行時(shí)會(huì)自動(dòng)使用適當(dāng)?shù)暮灻麨樵撐卸xBeginInvoke和EndInvoke方法
    2013-10-10
  • C#與C++之間類型的對(duì)應(yīng)知識(shí)點(diǎn)總結(jié)

    C#與C++之間類型的對(duì)應(yīng)知識(shí)點(diǎn)總結(jié)

    這篇文章主要介紹了C#與C++之間類型的對(duì)應(yīng)知識(shí)點(diǎn)總結(jié),對(duì)此有需要的朋友們可以參考下。
    2019-08-08
  • C#中類的異常處理詳解

    C#中類的異常處理詳解

    大家好,本篇文章主要講的是C#中類的異常處理詳解,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-02-02
  • c#構(gòu)造ColorComboBox(顏色下拉框)

    c#構(gòu)造ColorComboBox(顏色下拉框)

    這篇文章主要介紹了c#構(gòu)造ColorComboBox的代碼分享,大家參考使用吧
    2013-12-12

最新評(píng)論