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

C# 表達(dá)式樹Expression Trees的知識梳理

 更新時間:2017年01月04日 11:40:41   作者:反骨仔(二五仔)  
本篇文章主要介紹了表達(dá)式樹 Expression Trees的基礎(chǔ)知識:Lambda 表達(dá)式創(chuàng)建表達(dá)式樹;API 創(chuàng)建表達(dá)式樹;編譯表達(dá)式樹;執(zhí)行表達(dá)式樹;修改表達(dá)式樹等等,具有一定的參考價值,下面跟著小編一起來看下吧

目錄

  • 簡介
  • Lambda 表達(dá)式創(chuàng)建表達(dá)式樹
  • API 創(chuàng)建表達(dá)式樹
  • 解析表達(dá)式樹
  • 表達(dá)式樹的永久性
  • 編譯表達(dá)式樹
  • 執(zhí)行表達(dá)式樹
  • 修改表達(dá)式樹
  • 調(diào)試

簡介

表達(dá)式樹以樹形數(shù)據(jù)結(jié)構(gòu)表示代碼,其中每一個節(jié)點都是一種表達(dá)式,比如方法調(diào)用和 x < y 這樣的二元運(yùn)算等。

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

表達(dá)式樹還能用于動態(tài)語言運(yùn)行時 (DLR) 以提供動態(tài)語言和 .NET Framework 之間的互操作性。

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

若 lambda 表達(dá)式被分配給 Expression<TDelegate> 類型的變量,則編譯器可以發(fā)射代碼以創(chuàng)建表示該 lambda 表達(dá)式的表達(dá)式樹。 

C# 編譯器只能從表達(dá)式 lambda (或單行 lambda)生成表達(dá)式樹。

下列代碼示例使用關(guān)鍵字 Expression創(chuàng)建表示 lambda 表達(dá)式:

 Expression<Action<int>> actionExpression = n => Console.WriteLine(n);
 Expression<Func<int, bool>> funcExpression1 = (n) => n < 0;
 Expression<Func<int, int, bool>> funcExpression2 = (n, m) => n - m == 0;

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

通過 API 創(chuàng)建表達(dá)式樹需要使用Expression

下列代碼示例展示如何通過 API 創(chuàng)建表示 lambda 表達(dá)式:num => num == 0

//通過 Expression 類創(chuàng)建表達(dá)式樹
 // lambda:num => num == 0
 ParameterExpression pExpression = Expression.Parameter(typeof(int)); //參數(shù):num
 ConstantExpression cExpression = Expression.Constant(0); //常量:0
 BinaryExpression bExpression = Expression.MakeBinary(ExpressionType.Equal, pExpression, cExpression); //表達(dá)式:num == 0
 Expression<Func<int, bool>> lambda = Expression.Lambda<Func<int, bool>>(bExpression, pExpression); //lambda 表達(dá)式:num => num == 0

代碼使用Expression 類的靜態(tài)方法進(jìn)行創(chuàng)建。

三、解析表達(dá)式樹

下列代碼示例展示如何分解表示 lambda 表達(dá)式 num => num == 0 的表達(dá)式樹。

Expression<Func<int, bool>> funcExpression = num => num == 0;
 //開始解析
 ParameterExpression pExpression = funcExpression.Parameters[0]; //lambda 表達(dá)式參數(shù)
 BinaryExpression body = (BinaryExpression)funcExpression.Body; //lambda 表達(dá)式主體:num == 0
 Console.WriteLine($"解析:{pExpression.Name} => {body.Left} {body.NodeType} {body.Right}");

四、表達(dá)式樹永久性

表達(dá)式樹應(yīng)具有永久性(類似字符串)。這意味著如果你想修改某個表達(dá)式樹,則必須復(fù)制該表達(dá)式樹然后替換其中的節(jié)點來創(chuàng)建一個新的表達(dá)式樹。  你可以使用表達(dá)式樹訪問者遍歷現(xiàn)有表達(dá)式樹。第七節(jié)介紹了如何修改表達(dá)式樹。

五、編譯表達(dá)式樹

Expression<TDelegate> 類型提供了 Compile 方法以將表達(dá)式樹表示的代碼編譯成可執(zhí)行委托。

//創(chuàng)建表達(dá)式樹
 Expression<Func<string, int>> funcExpression = msg => msg.Length;
 //表達(dá)式樹編譯成委托
 var lambda = funcExpression.Compile();
 //調(diào)用委托
 Console.WriteLine(lambda("Hello, World!"));
 //語法簡化
 Console.WriteLine(funcExpression.Compile()("Hello, World!"));

六、執(zhí)行表達(dá)式樹

執(zhí)行表達(dá)式樹可能會返回一個值,也可能僅執(zhí)行一個操作(例如調(diào)用方法)。

只能執(zhí)行表示 lambda 表達(dá)式的表達(dá)式樹。表示 lambda 表達(dá)式的表達(dá)式樹屬于 LambdaExpressionExpression<TDelegate> 類型。若要執(zhí)行這些表達(dá)式樹,需要調(diào)用 Compile 方法來創(chuàng)建一個可執(zhí)行委托,然后調(diào)用該委托。

const int n = 1;
 const int m = 2;
 //待執(zhí)行的表達(dá)式樹
 BinaryExpression bExpression = Expression.Add(Expression.Constant(n), Expression.Constant(m));
 //創(chuàng)建 lambda 表達(dá)式
 Expression<Func<int>> funcExpression = Expression.Lambda<Func<int>>(bExpression);
 //編譯 lambda 表達(dá)式
 Func<int> func = funcExpression.Compile();
 //執(zhí)行 lambda 表達(dá)式
 Console.WriteLine($"{n} + {m} = {func()}");

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

該類繼承 ExpressionVisitor 類,通過 Visit 方法間接調(diào)用 VisitBinary 方法將 != 替換成 ==?;惙椒?gòu)造類似于傳入的表達(dá)式樹的節(jié)點,但這些節(jié)點將其子目錄樹替換為訪問器遞歸生成的表達(dá)式樹。 

internal class Program
 {
 private static void Main(string[] args)
 {
 Expression<Func<int, bool>> funcExpression = num => num == 0;
 Console.WriteLine($"Source: {funcExpression}");
 var visitor = new NotEqualExpressionVisitor();
 var expression = visitor.Visit(funcExpression);
 Console.WriteLine($"Modify: {expression}");
 Console.Read();
 }
 /// <summary>
 /// 不等表達(dá)式樹訪問器
 /// </summary>
 public class NotEqualExpressionVisitor : ExpressionVisitor
 {
 public Expression Visit(BinaryExpression node)
 {
 return VisitBinary(node);
 }
 protected override Expression VisitBinary(BinaryExpression node)
 {
 return node.NodeType == ExpressionType.Equal
  ? Expression.MakeBinary(ExpressionType.NotEqual, node.Left, node.Right) //重新弄個表達(dá)式:用 != 代替 ==
  : base.VisitBinary(node);
 }
 }
 }

八、調(diào)試

8.1 參數(shù)表達(dá)式

 ParameterExpression pExpression1 = Expression.Parameter(typeof(string));
 ParameterExpression pExpression2 = Expression.Parameter(typeof(string), "msg");

圖8-1

圖8-2

從 DebugView 可知,如果參數(shù)沒有名稱,則會為其分配一個自動生成的名稱。

 const int num1 = 250;
 const float num2 = 250;
 ConstantExpression cExpression1 = Expression.Constant(num1);
 ConstantExpression cExpression2 = Expression.Constant(num2);

圖8-3

圖8-4

從 DebugView 可知,float 比 int 多了個后綴 F。

 Expression lambda1 = Expression.Lambda<Func<int>>(Expression.Constant(250));
 Expression lambda2 = Expression.Lambda<Func<int>>(Expression.Constant(250), "CustomName", null);

圖8-5

圖8-6

觀察 DebugView ,如果 lambda 表達(dá)式?jīng)]有名稱,則會為其分配一個自動生成的名稱。

以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時也希望多多支持腳本之家!

相關(guān)文章

  • C#迷你猜數(shù)實例分析

    C#迷你猜數(shù)實例分析

    這篇文章主要介紹了C#迷你猜數(shù),實例分析C#操作數(shù)字及數(shù)組的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-03-03
  • C#調(diào)用WebService實例與開發(fā)教程(推薦)

    C#調(diào)用WebService實例與開發(fā)教程(推薦)

    下面小編就為大家分享一篇C#調(diào)用WebService實例與開發(fā)教程,具有很好的參考價值,希望對大家有所幫助。一起跟隨想過來看看吧
    2017-12-12
  • C#/VB.NET?實現(xiàn)彩色PDF轉(zhuǎn)為灰度PDF

    C#/VB.NET?實現(xiàn)彩色PDF轉(zhuǎn)為灰度PDF

    本文以C#代碼為例介紹如何實現(xiàn)將彩色PDF文件轉(zhuǎn)為灰度(黑白)的PDF文件,即將PDF文檔里面的彩色圖片或者文字等通過調(diào)用方法轉(zhuǎn)為文檔頁面為灰色調(diào)、無彩色效果的文檔??靵砀S小編一起學(xué)習(xí)吧
    2021-11-11
  • C#中參數(shù)個數(shù)可變的方法實例分析

    C#中參數(shù)個數(shù)可變的方法實例分析

    這篇文章主要介紹了C#中參數(shù)個數(shù)可變的方法,以一個簡單實例分析了C#中參數(shù)個數(shù)可變的方法,主要是使用params關(guān)鍵字來實現(xiàn)的,是C#編程中比較實用的技巧,需要的朋友可以參考下
    2014-11-11
  • C#實現(xiàn)Winform小數(shù)字鍵盤模擬器

    C#實現(xiàn)Winform小數(shù)字鍵盤模擬器

    本文主要介紹了C#實現(xiàn)Winform小數(shù)字鍵盤模擬器,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • 如何在C#中調(diào)用COM組件

    如何在C#中調(diào)用COM組件

    這篇文章主要介紹了如何在C#中調(diào)用COM組件,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • C#實現(xiàn)多線程下載文件的方法

    C#實現(xiàn)多線程下載文件的方法

    這篇文章主要介紹了C#實現(xiàn)多線程下載文件的方法,實例分析了C#多線程及文件傳輸?shù)南嚓P(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-08-08
  • C#折線圖控件使用方法詳解

    C#折線圖控件使用方法詳解

    這篇文章主要為大家詳細(xì)介紹了C#折線圖控件的使用方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • C# 泛型參數(shù)轉(zhuǎn)換

    C# 泛型參數(shù)轉(zhuǎn)換

    本文介紹了C# 泛型參數(shù)轉(zhuǎn)換的相關(guān)知識,具有很好的參考價值,下面跟著小編一起來看下吧
    2017-02-02
  • Unity3D實現(xiàn)飛機(jī)大戰(zhàn)游戲(2)

    Unity3D實現(xiàn)飛機(jī)大戰(zhàn)游戲(2)

    這篇文章主要為大家詳細(xì)介紹了Unity3D實現(xiàn)飛機(jī)大戰(zhàn)游戲的第二部分,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-06-06

最新評論