小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Linq之Expression高級篇(常用表達(dá)式類型)

 ThinkTank_引擎 2017-06-27

目錄

寫在前面

系列文章

變量表達(dá)式

常量表達(dá)式

條件表達(dá)式

賦值表達(dá)式

二元運(yùn)算符表達(dá)式

一元運(yùn)算符表達(dá)式

循環(huán)表達(dá)式

塊表達(dá)式

總結(jié)

寫在前面

首先回顧一下上篇文章的內(nèi)容,上篇文章介紹了表達(dá)式樹的解析和編譯。如果忘記了,可以通過下面系列文章提供的入口進(jìn)行復(fù)習(xí)。這篇文章將介紹常見的表達(dá)式類型。

常見的表達(dá)式類型都有個共同的基類Expression。創(chuàng)建這些類型的對象,是通過API的方式創(chuàng)建的(也就是Expression的靜態(tài)方法),首先引入命名空間:

1 using System.Linq.Expressions;

系列文章

Linq之Lambda表達(dá)式初步認(rèn)識

Linq之Lambda進(jìn)階

Linq之隱式類型、自動屬性、初始化器、匿名類

Linq之?dāng)U展方法

Linq之Expression初見

Linq之Expression進(jìn)階

變量表達(dá)式

在表達(dá)式樹中使用ParameterExpression或者ParameterExpression表達(dá)式表示變量類型,下面看一個例子,我們定義一個int類型的變量i:

  // ParameterExpression表示命名的參數(shù)表達(dá)式。
 ParameterExpression i = Expression.Parameter(typeof(int),"i");

或者使用

1 ParameterExpression j = Expression.Variable(typeof(int), "j");

通過f12轉(zhuǎn)到定義,發(fā)現(xiàn)這兩個方法的注釋幾乎是一樣的。靜態(tài)方法Parameter第一個參數(shù):定義的參數(shù)類型,第二個參數(shù):為參數(shù)名稱。

常量表達(dá)式

在表達(dá)式樹中使用ConstantExpression表達(dá)式表示具有常量值的表達(dá)式。,看一個例子,我們定義一個int類型的常量5.并將該值賦值給上面定義的變量i

復(fù)制代碼
1             // ParameterExpression表示命名的參數(shù)表達(dá)式。
2             ParameterExpression i = Expression.Parameter(typeof(int), "i");
3             //ParameterExpression j = Expression.Variable(typeof(int), "j");
4             ConstantExpression constExpr = Expression.Constant(5, typeof(int));
5             // 創(chuàng)建一個表示賦值運(yùn)算的 System.Linq.Expressions.BinaryExpression
6             //表示包含二元運(yùn)算符的表達(dá)式。
7             BinaryExpression binaryExpression = Expression.Assign(i, constExpr);
復(fù)制代碼

Constrant方法第一個參數(shù):常量,第二個參數(shù)為什么類型的常量。

這里提到了BinaryExpression表達(dá)式,該表達(dá)式標(biāo)識包含二元運(yùn)算符的表達(dá)式,類似與=,>這樣的二元表達(dá)式都可以使用BinaryExpression表達(dá)式來表示。

調(diào)試模式下,在自動窗口查看當(dāng)前表達(dá)式的DebugView屬性,這個屬性在調(diào)試表達(dá)式樹的時候是非常有用的:

變量:

常量:

二元表達(dá)式:

通過觀察上面的圖,可知變量調(diào)試模式下DebugView屬性將顯示前面帶有“$”符號的 ParameterExpression 變量名稱。那么如果參數(shù)沒有名稱,則會為其分配一個自動生成的名稱,例如 $var1 或 $var2(這里不再舉例)。

條件表達(dá)式

在很多時候,我們都需要使用條件表達(dá)式來過濾一些數(shù)據(jù),然后返回滿足條件的數(shù)據(jù),在表達(dá)式中有這樣一些表達(dá)式滿足你的需求。

常見運(yùn)算符

>,>=

<,<=

if....then:如果滿足條件那么..

if...then...else:如果滿足條件執(zhí)行某某代碼,否則執(zhí)行另外的邏輯

一個例子

IfThenElse方法

1 public static ConditionalExpression IfThenElse(
2     Expression test,
3     Expression ifTrue,
4     Expression ifFalse
5 )
復(fù)制代碼
 1             bool test = true;
 2             ConditionalExpression codition = Expression.IfThenElse(
 3                 //條件
 4                 Expression.Constant(test),
 5                 //如果條件為true,調(diào)用WriteLine方法輸出“條件為true”
 6                  Expression.Call(
 7                  null,
 8                  typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }),
 9                  Expression.Constant("條件為true")
10                  ),
11                 //如果條件false
12                   Expression.Call(
13                  null,
14                  typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }),
15                  Expression.Constant("條件為false")
16                  )
17                  );
18             //編譯表達(dá)式樹,輸出結(jié)果
19             Expression.Lambda<Action>(codition).Compile()();
復(fù)制代碼

輸出結(jié)果

 例子描述:條件test包裝為常量表達(dá)式,因?yàn)閠est為true,所以執(zhí)行iftrue的表達(dá)式,并調(diào)用WriteLine方法打印出信息。

賦值表達(dá)式

=

還以上面為變量i賦值的例子為例

1             ParameterExpression i = Expression.Parameter(typeof(int), "i");
2             //ParameterExpression j = Expression.Variable(typeof(int), "j");
3             ConstantExpression constExpr = Expression.Constant(5, typeof(int));
4             // 創(chuàng)建一個表示賦值運(yùn)算的 System.Linq.Expressions.BinaryExpression
5             //表示包含二元運(yùn)算符的表達(dá)式。
6             BinaryExpression binaryExpression = Expression.Assign(i, constExpr);

+=

1 BinaryExpression b2 = Expression.AddAssign(i, constExpr);

-=

1 BinaryExpression b3 = Expression.SubtractAssign(i, constExpr);

*=

 BinaryExpression b4 = Expression.MultiplyAssign(i, constExpr);

/=

1 BinaryExpression b5= Expression.DivideAssign(i, constExpr);

舉一個例子

復(fù)制代碼
 1  ParameterExpression i = Expression.Parameter(typeof(int), "i");
 2             BlockExpression block = Expression.Block(
 3                 new[] { i },
 4                 //賦初值 i=5
 5                 Expression.Assign(i, Expression.Constant(5, typeof(int))),
 6                 //i+=5 10
 7                 Expression.AddAssign(i, Expression.Constant(5, typeof(int))),
 8                 //i-=5 5
 9                 Expression.SubtractAssign(i, Expression.Constant(5, typeof(int))),
10                 //i*=5 25
11                Expression.MultiplyAssign(i, Expression.Constant(5, typeof(int))),
12                 //i/=5 5
13                Expression.DivideAssign(i, Expression.Constant(5, typeof(int)))
14                );
15             Console.WriteLine(Expression.Lambda<Func<int>>(block).Compile()());
復(fù)制代碼

結(jié)果

二元運(yùn)算符表達(dá)式

在上面也提到了部分二元運(yùn)算符表達(dá)式,類似加減乘除這樣的運(yùn)算符,對于二元運(yùn)算符,就不再舉例。這些返回的表達(dá)式樹,都可以使用BinaryExpression來接收,或者使用基類Expression接收,或者更省事,使用var關(guān)鍵字。

一元運(yùn)算符表達(dá)式

類似++,--運(yùn)算符

i++等價于i=i+1,運(yùn)算順序就是i先加1,然后再賦值給i。在表達(dá)式書中使用Expression的PostIncrementAssign方法來進(jìn)行自增或者自減操作。返回結(jié)果為UnaryExpression類型,同樣可以使用基類Expression接收,或者var。

循環(huán)表達(dá)式

在表達(dá)式樹中使用Expression的Loop方法實(shí)現(xiàn)循環(huán)。

塊表達(dá)式

在前面的文章中,也說了不能使用Lambda方式創(chuàng)建帶塊級的表達(dá)式樹,不然會有如下的錯誤

通過API的方式可以創(chuàng)建塊級表達(dá)式樹,其中Expression的Block方法功不可沒。例如上面的加減乘除的例子中,可以包括多個Expression。

那么,下面就舉一個包含自增的一元表達(dá)式,循環(huán)的表達(dá)式塊,并輸出結(jié)果。

輸出1-100之間的所有偶數(shù)。

復(fù)制代碼
 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             //變量i
 6             ParameterExpression i = Expression.Parameter(typeof(int), "i");
 7             //跳出循環(huán)
 8             LabelTarget label = Expression.Label();
 9             BlockExpression block = Expression.Block(
10                 new[] { i },
11                 //為i賦初值
12                 Expression.Assign(i, Expression.Constant(1, typeof(int))),
13                 Expression.Loop(
14                     Expression.IfThenElse(
15                       //如果i<=100
16                       Expression.LessThanOrEqual(i, Expression.Constant(100, typeof(int))),
17                      //如果為true.進(jìn)入循環(huán)體
18                         Expression.Block(
19                              Expression.IfThen(
20                              //條件i%2==0;
21                                     Expression.Equal(Expression.Modulo(i, Expression.Constant(2, typeof(int))), 
22                                     Expression.Constant(0, typeof(int))),
23                                     Expression.Call(typeof(Console).GetMethod("WriteLine", 
24                                     new Type[] { typeof(int) }), new[] { i })),
25                              //i++
26                              Expression.PostIncrementAssign(i)
27                 ),
28                 //如果i>100
29                 Expression.Break(label)),
30                 label
31                 ));
32             Expression.Lambda<Action>(block).Compile()();
33             Console.Read();
34         }
35     }
復(fù)制代碼

結(jié)果

總結(jié)

本篇文章介紹了幾種常見的表達(dá)式類型,當(dāng)然,還有很多并沒有列出,比如switch case,try catch等。如果在項(xiàng)目中需要創(chuàng)建復(fù)雜的表達(dá)式樹,Expression的靜態(tài)方法Block是必不可少的。希望通過本篇的學(xué)習(xí),對你了解Expression有所幫助。

參考文章

https://msdn.microsoft.com/zh-cn/library/dd323961(v=vs.110).aspx

https://msdn.microsoft.com/zh-cn/library/bb397951.aspx

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多