什麼是表示式樹?
表示式樹又稱為表示式目錄樹,以資料形式表示語言級**。所有的資料都儲存在樹結構中,每個結點表示乙個表示式(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平台中引入了 邏輯即資料 的概念。也就是說,我們可以在 裡使用高階語言的形式編寫一段邏輯,但是這段邏輯最終會被儲存為資料。正因為如此,我們可以使用...