表示式樹和泛型委託

2021-04-28 10:36:28 字數 3815 閱讀 2578

什麼是表示式樹?

表示式樹又稱為表示式目錄樹,以資料形式表示語言級**。所有的資料都儲存在樹結構中,每個結點表示乙個表示式(expression)。要想手動生成表示式樹我們需要引用system.linq.expressions 命名空間,最重要的乙個類是expression,它是所有表示式的基類。例如:

1:引數表示式:parameterexpression,就是乙個方法中的引數,例如 search(string key),key可以看成是乙個引數表示式。

2:二元表示式:binaryexpression,例如a+b等。

3:方法呼叫表示式:methodcallexpression,例如:自定義linq提供程式中實現orderby 的操作:

methodcallexpression orderbycallexpression 

=expression.call(

typeof

(queryable),

"orderby",

newtype ,

wherecallexpression,

expression.lambda

<

func

<

string

, string

>>

(pe, 

newparameterexpression ));

4:常數表示式:constantexpression,例如數值5。

5:欄位或屬性表示式:memberexpression,例如str.length。expression.property(pe, typeof(string).getproperty("length"));

6:帶有條件運算的表示式:conditionalexpression。

7:描述lambda表示式:lambdaexpression

8:一元運算子的表示式:unaryexpression

9:表示式和型別之間的相關操作:typebinaryexpression

等等,它們都繼承expression。

泛型委託:

表示式樹經常與泛型委託一起使用,這裡簡單介紹下什麼是泛型委託。func)>) 泛型委託:封裝乙個具有乙個引數並返回 tresult 引數指定的型別值的方法。如果想增加引數可以寫成func)>) 等。這種方法比起傳統的顯示宣告委託的方法從**結構上要簡化不少,我們不用特意去申請乙個delegate,所有的委託都可以用泛型委託來代替。這裡簡單來實現乙個算術表示式來說明泛型委託的好處。

算術表達:(a+b)^b

1:傳統的顯示申明委託方式。

1):申明乙個委託:

//////

(a+b)^b 委託

///

///para 1

///para 2

///public

delegate

double

powercompute(

double

num_1, 

double

num_2);

2):編碼委託對應的方法體

//////

(a+b)^b方法

///

///para 1

///para 2

///public

static

double

getpowercompute(

double

num_1, 

double

num_2)

3):呼叫:

double

dresult =0

;powercompute pc 

=getpowercompute;

dresult 

=pc(2, 

2);console.writeline(dresult.tostring());

2:泛型委託實現:

1):編碼委託對應的方法體,方法同上面**中第二步。

2):呼叫

func

<

double

,double

,double

>fc=

getpowercompute;

dresult 

=fc(2, 

2);console.writeline(dresult.tostring());

表示式樹的執行:

表示式樹和泛型委託:   這裡實現乙個簡單的表示式樹,實現(a+b)^b, 過程中需要知道以下三個比較重要的方法。

1:expression)>):以表示式目錄樹的形式將強型別 lambda 表示式表示為資料結構。

2:expression.lambda方法:建立乙個表示 lambda 表示式的表示式目錄樹。

3:expression)>).compile:將表示式目錄樹描述的 lambda 表示式編譯為可執行**。

下面是(a+b)^b的表示式樹生成可執行**並且在客戶端進行呼叫的**:

parameterexpression penum_1 

=expression.parameter(

typeof

(double

), "

num_1");

parameterexpression penum_2 

=expression.parameter(

typeof

(double

), "

num_2");

binaryexpression _be 

=expression.add(penum_1, penum_2);

binaryexpression _be2 

=expression.power(_be, penum_2);

expression

<

func

<

double

, double

, double

>>

ef =

expression.lambda

<

func

<

double

, double

, double

>>

(_be2, 

newparameterexpression );

func

<

double

, double

, double

>

cf =

ef.compile();

return

cf(num_1 ,num_2 );

下面是(a+b)^b的表示式樹的關係圖

表示式樹的修改:

表示式目錄樹是不可變的,這意味著不能直接修改表示式目錄樹。若要更改表示式目錄樹,必須建立現有表示式目錄樹的乙個副本,並在建立副本的過程中執行所需更改。您可以使用表示式目錄樹訪問器遍歷現有表示式目錄樹,並複製它訪問的每個節點。我們可以建立自定義類來繼承expressionvisitor,在自定義類中重定相應方式來達到修改表示式樹的目的。 

泛型委託 Lambda表示式

發信人 joshuag 秦之魅 加菲 我懷念的 信區 dotnet 標 題 閃電,看這個,泛型委託 lambda表示式 發信站 武漢白雲黃鶴站 2008年01月21日15 46 01 星期一 站內信件 我覺得你給出的那個委託的第二個引數不需要用泛型,這樣 public delegate void g...

c 中泛型表示式樹備忘

c 3.0中引入了表示式樹,使用泛型表示式樹可以方便的解決問題。舉乙個簡單的例子,我們可以使用它來完成不同型別的數值的加減乘除。首先,來看一下簡單的思路 下述 僅僅以加法運算來示例 static class calculate 然而這個 編譯是不能通過的,因為泛型不可以進行相加的操作。這種簡單的思路...

學習記錄。(4 6)表示式樹,泛型

1.表示式樹 1 邏輯即資料,linq to everything net 3.5中新增的表示式樹 expression tree 特性,第一次在.net平台中引入了 邏輯即資料 的概念。也就是說,我們可以在 裡使用高階語言的形式編寫一段邏輯,但是這段邏輯最終會被儲存為資料。正因為如此,我們可以使用...