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

C#表達(dá)式樹(shù)的基本用法講解

 更新時(shí)間:2020年12月02日 08:54:47   作者:yangyang  
這篇文章主要介紹了C#表達(dá)式樹(shù)的基本用法講解,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下

   表達(dá)式樹(shù)使用一種類似樹(shù)的結(jié)構(gòu)來(lái)表示代碼,它的每個(gè)節(jié)點(diǎn)都是一個(gè)表達(dá)式,比如方法調(diào)用和x<y這樣的二元運(yùn)算等。我們可以對(duì)表達(dá)式樹(shù)的內(nèi)容進(jìn)行編輯和運(yùn)算,這樣能夠動(dòng)態(tài)修改可執(zhí)行代碼,以及動(dòng)態(tài)創(chuàng)建查詢等。我們可以使用匿名lambda表達(dá)式或者C# API來(lái)創(chuàng)建表達(dá)式樹(shù)。

   這一系列文章,主要是對(duì)C#表達(dá)式樹(shù)的一種總結(jié),基本知識(shí)參考MSDN的內(nèi)容 這部分內(nèi)容可以直接到MSDN上查看,后面的幾篇文章主要分享一下,在工作中碰到的應(yīng)用到表達(dá)式樹(shù)的部分,謹(jǐn)做為記錄和分享。

生成表達(dá)式樹(shù)

通過(guò)lambda表達(dá)式創(chuàng)建表達(dá)式樹(shù)
    可以通過(guò)將lambda表達(dá)式賦值給Expression<TDelegate>類型的變量,編譯器可以自動(dòng)生成創(chuàng)建該lambda表達(dá)式的表達(dá)式樹(shù)。C#編譯器只能從lambda表達(dá)式生成表達(dá)式樹(shù),只能是單行l(wèi)ambda表達(dá)式,不能解析多行l(wèi)ambda語(yǔ)句,如下,可以通過(guò)一下方式創(chuàng)建lambda表達(dá)式 num=>num<5的表達(dá)式樹(shù):

Expression<Func<int, bool>> lambda = num => num < 5; 

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

   使用API創(chuàng)建表達(dá)式,需要使用Expression類,這個(gè)類包含了創(chuàng)建特定類型表達(dá)式樹(shù)節(jié)點(diǎn)的靜態(tài)工廠方法,比如表示參數(shù)的變量ParameterExpression,表示方法調(diào)用的MethodExpression。ParameterExpression,MethodExpression以及其他特定的表達(dá)式類型都在System.Linq.Expression命名空間里定義,這些類型都派生于Expression抽象類。

  下面的例子是使用API方式創(chuàng)建num=>num<5的lambda表達(dá)式對(duì)應(yīng)的表達(dá)式樹(shù):

ParameterExpression numPara = Expression.Parameter(typeof(int), "num");//參數(shù)num
ConstantExpression five = Expression.Constant(5, typeof(int));//常數(shù)5

BinaryExpression numLessThanFive = Expression.LessThan(numPara, five);
Expression<Func<int, bool>> lambda1 = Expression.Lambda<Func<int, bool>>(numLessThanFive, new ParameterExpression[] { numPara });

    從.NET Framework 4開(kāi)始,表達(dá)式樹(shù)API還支持賦值以及流程控制,比如循環(huán),條件塊和try ... catch塊等。相對(duì)于通過(guò)lambda表達(dá)式創(chuàng)建表達(dá)式樹(shù),可以利用API創(chuàng)建更加復(fù)雜的表達(dá)式樹(shù),比如下面使用API創(chuàng)建數(shù)字階乘的表達(dá)式樹(shù):

//參數(shù)value
ParameterExpression value = Expression.Parameter(typeof(int), "value");
//本地變量
ParameterExpression result = Expression.Parameter(typeof(int), "result");
//標(biāo)簽,用來(lái)跳出循環(huán)
LabelTarget label = Expression.Label(typeof(int));
//創(chuàng)建表達(dá)式塊
BlockExpression block = Expression.Block(
 //添加本地參數(shù)result
 new[] { result },
 //result=1 賦值
 Expression.Assign(result, Expression.Constant(1)),
 //循環(huán)
 Expression.Loop(
  //循環(huán)條件
  Expression.IfThenElse(
   //如果 value>1
   Expression.GreaterThan(value, Expression.Constant(1)),
   //則 result*=value--;
   Expression.MultiplyAssign(result, Expression.PostDecrementAssign(value)),
   //否則跳出loop循環(huán)。跳到label的語(yǔ)句執(zhí)行
   Expression.Break(label, result)
   ),
   label
  )
);
//編譯表達(dá)式樹(shù)
Func<int, int> factor = Expression.Lambda<Func<int, int>>(block, value).Compile();
//執(zhí)行,輸出結(jié)果120
Console.WriteLine(factor(5));

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

  在獲取了表達(dá)式樹(shù)之后,如何獲取表達(dá)式樹(shù)的每一個(gè)部分,這個(gè)在有些情況下非常有用,下面這個(gè)例子展示了如何獲取num=>num<5的各個(gè)部分。

Expression<Func<int, bool>> expreTree = num => num < 5;

ParameterExpression param = (ParameterExpression)expreTree.Parameters[0];//num
BinaryExpression operation = (BinaryExpression)expreTree.Body;//<
ParameterExpression left = (ParameterExpression)operation.Left;//num
ConstantExpression right = (ConstantExpression)operation.Right;//5
                //output Decomposed expression: num => num LessThan 5 
Console.WriteLine("Decomposed expression:{0} = > {1} {2} {3}", param.Name, left.Name, operation.NodeType, right.Value);

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

  Expression<TDelegate>類型有Compile方法,可以將表達(dá)式樹(shù)編譯成對(duì)應(yīng)的TDelegate委托類型,使用方法如下:

// 創(chuàng)建表達(dá)式樹(shù)
Expression<Func<int, bool>> expr = num => num < 5;
// 將表達(dá)式樹(shù)編譯成對(duì)應(yīng)委托 
Func<int, bool> result = expr.Compile();
//調(diào)用委托方法,輸出True
Console.WriteLine(result(4));
//也可以直接編譯后調(diào)用,輸出True
Console.WriteLine(expr.Compile()(4));

再比如,下面例子演示了,創(chuàng)建一個(gè)表達(dá)式樹(shù),然后編譯執(zhí)行:

//創(chuàng)建表達(dá)式樹(shù)的執(zhí)行邏輯
BinaryExpression be = Expression.Power(Expression.Constant(2D), Expression.Constant(3D));
//創(chuàng)建表達(dá)式樹(shù)
Expression<Func<double>> le = Expression.Lambda<Func<double>>(be);
//編譯表達(dá)式樹(shù)
Func<double> compileExpression = le.Compile();
//執(zhí)行l(wèi)ambda表達(dá)式,獲得結(jié)果8
double result = compileExpression();
Console.WriteLine(result);

表達(dá)式樹(shù)的修改

   表達(dá)式樹(shù)是不可變對(duì)象(immutable),跟string類似,不能直接修改,只能復(fù)制一個(gè)然后重新構(gòu)造。具體參考MSDN How to modify expression trees (C#).

結(jié)語(yǔ)

  本篇全部?jī)?nèi)容參考MSDN上表達(dá)式樹(shù)部分的內(nèi)容,如果有基礎(chǔ)建議直接看,這里只是個(gè)人作為筆記,也是表達(dá)式樹(shù)的最基礎(chǔ)部分,后文會(huì)介紹表達(dá)式樹(shù)的一些用法。

以上就是C#表達(dá)式樹(shù)的基本用法講解的詳細(xì)內(nèi)容,更多關(guān)于C#表達(dá)式樹(shù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C#獲取機(jī)器碼的方法詳解(機(jī)器名,CPU編號(hào),硬盤編號(hào),網(wǎng)卡mac等)

    C#獲取機(jī)器碼的方法詳解(機(jī)器名,CPU編號(hào),硬盤編號(hào),網(wǎng)卡mac等)

    這篇文章主要介紹了C#獲取機(jī)器碼的方法,結(jié)合實(shí)例形式詳細(xì)分析了C#獲取硬件機(jī)器名、CPU編號(hào)、硬盤編號(hào)、網(wǎng)卡mac等信息的相關(guān)實(shí)現(xiàn)方法,需要的朋友可以參考下
    2016-07-07
  • C# Path類---文件路徑解讀

    C# Path類---文件路徑解讀

    這篇文章主要介紹了C# Path類---文件路徑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • C#實(shí)現(xiàn)凍結(jié)Excel窗口以鎖定行列或解除凍結(jié)

    C#實(shí)現(xiàn)凍結(jié)Excel窗口以鎖定行列或解除凍結(jié)

    在處理大型Excel工作簿時(shí),有時(shí)候我們需要在工作表中凍結(jié)窗格,這樣可以在滾動(dòng)查看數(shù)據(jù)的同時(shí)保持某些行或列固定不動(dòng),下面我們就來(lái)看看如何使用C#實(shí)現(xiàn)凍結(jié)Excel窗口吧
    2024-04-04
  • unity實(shí)現(xiàn)物體延時(shí)出現(xiàn)

    unity實(shí)現(xiàn)物體延時(shí)出現(xiàn)

    這篇文章主要為大家詳細(xì)介紹了unity實(shí)現(xiàn)物體延時(shí)出現(xiàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • C#計(jì)算字符串哈希值(MD5、SHA)的方法小結(jié)

    C#計(jì)算字符串哈希值(MD5、SHA)的方法小結(jié)

    這篇文章主要介紹了C#計(jì)算字符串哈希值(MD5、SHA)的方法,以實(shí)例形式較為詳細(xì)的分析總結(jié)了C#計(jì)算字符串哈希值的各種常用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-08-08
  • C#?線程簡(jiǎn)單介紹及使用詳情

    C#?線程簡(jiǎn)單介紹及使用詳情

    這篇文章主要介紹了C#?線程簡(jiǎn)單介紹及使用詳情,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-08-08
  • C#使用iTextSharp庫(kù)將圖片轉(zhuǎn)換為PDF

    C#使用iTextSharp庫(kù)將圖片轉(zhuǎn)換為PDF

    iTextSharp 是一個(gè)開(kāi)源的 .NET 庫(kù),主要用于創(chuàng)建和操作 PDF 文檔,本文主要介紹了如何使用 C# 和 iTextSharp 將圖片轉(zhuǎn)換為 PDF 的功能,需要的可以參考下
    2024-12-12
  • C# Lambda表達(dá)式select()和where()的區(qū)別及用法

    C# Lambda表達(dá)式select()和where()的區(qū)別及用法

    這篇文章主要介紹了C# Lambda表達(dá)式select()和where()的區(qū)別及用法,select在linq中一般會(huì)用來(lái)提取最后篩選的元素集合,在lambda表達(dá)式中通常用where得到元素集合,需要的朋友可以參考下
    2023-07-07
  • WinForm中實(shí)現(xiàn)雙向數(shù)據(jù)綁定的示例詳解

    WinForm中實(shí)現(xiàn)雙向數(shù)據(jù)綁定的示例詳解

    在開(kāi)發(fā)WinForm應(yīng)用程序時(shí),常常需要將數(shù)據(jù)模型與用戶界面進(jìn)行同步,傳統(tǒng)的做法是手動(dòng)監(jiān)聽(tīng)UI變化并更新數(shù)據(jù)模型,這種方式不僅繁瑣而且容易出錯(cuò),為了解決這個(gè)問(wèn)題,許多現(xiàn)代UI框架都支持雙向數(shù)據(jù)綁定,本文介紹WinForm中實(shí)現(xiàn)雙向數(shù)據(jù)綁定的示例,需要的朋友可以參考下
    2025-05-05
  • C# SMTP發(fā)送郵件的示例

    C# SMTP發(fā)送郵件的示例

    這篇文章主要介紹了C# SMTP發(fā)送郵件的示例,幫助大家更好的理解和學(xué)習(xí)c#,感興趣的朋友可以了解下
    2020-12-12

最新評(píng)論