程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Linq Lambda表達式全面分析

Linq Lambda表達式全面分析

編輯:關於.NET

在向大家詳細介紹Linq Lambda表達式之前,首先讓大家了解下expr是什麼樣的東西,然後全面介紹 Linq Lambda表達式。

介紹Linq Lambda表達式之前,先看一個例子:

Expression<Func<string, bool>> expr = o => o.Length >  10;

初次接觸Linq Lambda表達式的人可能會被搞迷糊,這樣的語句到底是什麼意思,怎麼樣工作,原理又 是什麼。

逐級分析以上語句,分為兩個部分,以等號為界。

第一部分是變量類型的申明:Expression<Func<string, bool>> expr,表示expr這個變 量是一個Linq Lambda表達式,這個表達式符合這樣的一種委托:bool DelegateName(string obj)。

第二部分是表達式的聲明o => o.Length > 10,這個“=>”是Lambda操作符,讀作“轉到” ,必須把=>左右看成是一個整體,因為這實際是一個匿名方法,“=>”左邊是方法傳入參數的申明 ,右邊是函數體,如果用常規的表示方法,可以寫成如下形式:

bool MethodName(string o)
{
return o.Length > 10;
}

仔細觀察兩部分拆解以後的形式其實不難發現,第一部分的工作是定義了一個匿名的委托,而第二部 分則是符合這個匿名委托的一個方法,由於這個方法沒有明確給定名稱,因此稱為匿名方法。

那麼,expr到底又是什麼樣的東西。有一點必須明確的是,expr表示絕對不是這個匿名方法的返回值 ,而是這個匿名方法中所有表達式的 System.Linq.Expressions.Expression形式。也就是說,在expr中 ,這個函數體裡所有的表達式已經被拆解成一個一個的單元,每一個單元都是一種 System.Linq.Expressions.Expression的派生類。由於表達式和表達式之前存在著上下級的關系,因此所 有的表達式呈現一種樹狀結構,稱為表達式樹。

一個匿名方法是如何轉換為表達式樹的呢?這個問題其實不用太過關心,因為C#編譯器在對程序編譯 的時候已經將上述第二部分的內容自動轉換為相應的表達式樹了。上述例子中編譯的結果通過Reflector 反編譯出來的內容如下所示:

1. ParameterExpression CS$0$0000;
2. Expression<Func<string, bool>> expr =  Expression.Lambda<Func<string,
bool>>(Expression.GreaterThan(Expression.Property(CS$0$0000 = Expression.
Parameter(typeof(string), "o"), (MethodInfo) methodof(string.get_Length)),
Expression.Constant(10, typeof(int))), new ParameterExpression[] { CS$0$0000  });

這串代碼看起來有點糊,我把代碼梳理了一下使得它更容易讀,如下所示:

Expression<Func<string, bool>> expr;

// 創建表示參數的表達式。
ParameterExpression paramExpr = Expression.Parameter(typeof(string), "o");
// 獲取表示System.String.Length屬性的System.Reflection.PropertyInfo對象。
PropertyInfo propInfo = typeof(string).GetProperty
("Length", BindingFlags.Instance | BindingFlags.Public);
// 創建訪問System.String.Length屬性的表達式。
MemberExpression memberExpr = Expression.Property(paramExpr, propInfo);
// 創建一個表示常量10的表達式。
ConstantExpression constExpr = Expression.Constant(10, typeof(int));
// 創建表示左邊大於右邊的二分表達式。
BinaryExpression greaterThanExpr = Expression.GreaterThan(memberExpr,  constExpr);
// 通過上述二分表達式創建一個Lambda表達式。
expr = Expression.Lambda<Func<string, bool>>(greaterThanExpr,  paramExpr);

是不是好麻煩啊?呵呵,好在這些工作已經在編譯的時候完成了,不需要我們手工創建,除非你想動 態創建表達式。關於如何動態創建表達式,我在這裡就先不詳細說明了,將在下一博裡再詳述。

綜上所述,對待Linq Lambda表達式,最基本一個原則是不要把表達式看成了語句的運算結果,而應該 看成這些語句本身,也就是把語句作為對象來處理。語句和語句之間通過表達式樹來關聯,而從語句轉換 為表達式樹已由編譯器自動完成,不需要人工介入。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved