C 高階程式設計(九) 表示式樹

2021-12-30 05:23:57 字數 2261 閱讀 2473

表示式樹的設計是基於"code as data"的思想,它把**表示成樹狀的資料結構,樹狀結構中的每個節點都是乙個表示式(這個表示式是乙個廣義的概念,並不是程式語言中所指的表示式語法),因此稱為表示式樹。

表示式樹的本質在於將**組織在資料段,而不是**段,這對於執行時更改**是非常重要的。

system.linq.expressions命名空間下含有很多類來表示不同的表示式,這些類都繼承自抽象的expression基類,expression含有豐富的靜態方法用於建立各種各樣的表示式類。

一、程式設計方式構建表示式樹

下面的**以程式設計的方式構建表示式樹

[csharp] 

expression firstarg = expression.constant(2); 

expression secondarg = expression.constant(3); 

expression add = expression.add(firstarg, secondarg); 

console.writeline(add); 

上面的**建立的表示式樹如圖:

二、表示式樹與**(編譯表示式樹成為**)

將表示式樹轉化為**的關鍵點在於expression類,繼承關係如圖:

可以使用expression.lambda方法建立expression物件,expression物件包含compile方法,用於將表示式編譯成可執行**並生成表示其lambda表示式的**物件,

下面的**表示轉換過程:

[csharp] 

expression firstarg = expression.constant(2); 

expression secondarg = expression.constant(3); 

expression add = expression.add(firstarg, secondarg); 

func compiled = expression.lambda>(add).compile(); 

console.writeline(compiled()); 

三、表示式樹與lambda表示式(lambda表示式轉換為表示式樹)

可以通過lambda表示式構造expression物件:

[csharp] 

expression> expression = 

(x, y) => x.startswith(y); 

var compiled = expression.compile(); 

console.writeline(compiled("first", "second")); 

console.writeline(compiled("first", "fir")); 

下面的**與之等價,但是用程式設計方式構建表示式樹:

[csharp]  

methodinfo method = typeof(string).getmethod 

("startswith", new ); 

var target = expression.parameter(typeof(string), "x"); 

var methodarg = expression.parameter(typeof(string), "y"); 

expression methodargs = new ; 

expression call = expression.call(target, method, methodargs); 

var lambdaparameters = new ; 

var lambda = expression.lambda> 

(call, lambdaparameters); 

var compiled = lambda.compile(); 

console.writeline(compiled("first", "second")); 

console.writeline(compiled("first", "fir")); 

目前,並不是所有的lambda表示式都能轉換成表示式樹,只有單一表示式的lambda表示式才可以轉化為表示式樹,而且表示式中不能包含賦值。

四、表示式樹與linq

表示式樹主要應用在linq to sql中,linq to sql的目標是將linq請求轉換為sql語句(普通文字),但是在轉換過程中我們又不想失去編譯時型別檢查,所以linq to sql的設計思想是將linq查詢轉化成表示式樹(查詢中使用的lambda表示式按照某種演算法轉換為表示式樹),然後再將表示式樹轉換成需要執行的sql語句。

C 高階程式設計(八) Lambda表示式

lambda 表示式 是乙個匿名函式,它可以包含表示式和語句,並且可用於建立委託或表示式樹型別。所有 lambda 表示式都使用 lambda 運算子 該運算子讀為 goes to 該 lambda 運算子的左邊是輸入引數 如果有 右邊包含表示式或語句塊。lambda表示式的基本形式是 explic...

C 表示式樹

在使用 ef 開中我們經常使用 xx.where p p.name 張三 查詢資料,之把能這樣是因為 ef 框架會把這些c 轉成sql語句,其中主要用到的就是表示式樹,今天就來學習一下表示式樹。func func a,b a b expressionint,int,int expression a,...

表示式 表示式樹 表示式求值

總時間限制 1000ms 記憶體限制 65535kb 描述 眾所周知,任何乙個表示式,都可以用一棵表示式樹來表示。例如,表示式a b c,可以表示為如下的表示式樹 a b c 現在,給你乙個中綴表示式,這個中綴表示式用變數來表示 不含數字 請你將這個中綴表示式用表示式二叉樹的形式輸出出來。輸入輸入分...