[.net 面向對象程序設計進階] (6) Lamda表達式(二) 表達式樹快速入門
本節導讀:
認識表達式樹(Expression Tree),學習使用Lambda創建表達式樹,解析表達式樹。
學習表達式在程序設計中的優點:比如構造動態查詢、動態構造表達式樹完成未知對象屬性訪問,比反射的性能高出很多。我們可以說表達式樹才是Lambda的精髓,是我們必須要熟練掌握並靈活運用的。
1.關於表達式樹(Expression Tree)
表達式樹以樹形數據結構表示代碼,其中每一個節點都是一種表達式,比如方法調用和 x < y 這樣的二元運算等。
表達式樹,對於剛接觸的人來說,比較難以理解。那么什么是表達式樹,通俗點來說,就是使用一種樹形的數據結構來緩存表達式。
2.表達式樹能幫我們做點什么?
上面我們說了表達式樹是一種數據結構,那么為什么要把表達式定義成表達式樹呢,轉成一種數據結構,能幫我們做點什么?先明確了他能為我們帶來什么,才有動力繼續看下去。
說到他的作用,當然是非常有用的,我們在很多場景下都要使用他,當表達式變為一個表達式樹的數據結構時,表達式就變為一個對象,你可以對表達式樹中的對象元素(表達式的代碼)進行編輯和運算。下面列舉幾種常用的:
- 通過修改表達式樹能夠動態修改可執行代碼
- 在不同數據庫中執行 LINQ 查詢
- 創建動態查詢。
- 完成類似反射訪問未知對象屬性,通過動態構造表達式樹,生成委托。
3. 表達式樹的創建
命名空間: System.Linq.Expressions
創建表達式樹示例:
Expression<Func<int, int, bool>> expression = (num,num2)=> num < num2;
這個語句包含三個部分:
- 一個聲明: Func<int, int, int> function
- 一個等號: =
- 一個lambda表達式: (num,num2)=> num < num2;
expression 就是一個類型為Expression<T>的表達式樹,可以看出,他並非是一個可執行代碼,而是一種表達式樹的數據結構。
4. 表達式樹結構的構成
Expression<Func<int, int, bool>> expression = (num,num2)=> num < num2;
通過監視我們定義好的表達式樹,可以看到其構成
下面我們對幾個重要屬性說明:
- Body: 得到表達式的主體。例:(num < num2) 其中,Body中又包含屬性Left和Right 在上例中分別為num和num2
- Parameters: 得到lambda表達式的參數。 例 {num,num2}
- NodeType: 獲取樹的節點的ExpressionType。共45種不同值,包含所有表達式節點各種可能的類型。例如返回常量,例如返回參數,例如取兩個值的小值(<),例如取兩個值的大值(>),例如將值相加(+),等等。例:Lambda
- Type: 獲取表達式的一個靜態類型。 例:Func<int, int, bool>。
- ReturnType:這個是表達式的返回類型 例:bool
還有一些其他屬性Name、CanReduce等,這些不是很常用。
5.解析表達式樹
我們了解了表達式樹結構的組成,解析表達式變得相當容易了,下面我們直接通過一個示例來完成對一個表達式樹的解析:
//表達式樹(Expression) Expression<Func<int, int, bool>> expression = (x, y) => x!=0 && x==y+1; BinaryExpression exr = expression.Body as BinaryExpression; IReadOnlyList<ParameterExpression> param = expression.Parameters as IReadOnlyList<ParameterExpression>; BinaryExpression left = exr.Left as BinaryExpression; BinaryExpression right = exr.Right as BinaryExpression; ExpressionType exrType = exr.NodeType; ParameterExpression leftLeft = left.Left as ParameterExpression; ConstantExpression leftRight = left.Right as ConstantExpression; ExpressionType leftType = left.NodeType; ParameterExpression rightLeft = right.Left as ParameterExpression; BinaryExpression rightRight = right.Right as BinaryExpression; ExpressionType rightType = right.NodeType; ParameterExpression rightRightLeft = rightRight.Left as ParameterExpression; ExpressionType rightRightType = rightRight.NodeType; ConstantExpression rightRightRight = rightRight.Right as ConstantExpression; Console.WriteLine(exr.ToString());
表達式樹的解析,里面的元素無非就下面幾種:
A.BinaryExpression 包含二元運算符的表達式
B.ParameterExpression命名的參數表達式 ,一般是一組參數集合IReadOnlyList<ParameterExpression>
C.ConstantExpression常量值的表達式
D.ExpressionType節點類型
對於上面示例的表達樹結構,我用圖例的方式展現如下:
對於上面的結構,我們可以按上面代碼中的對象元素變量與之一一對應如下圖:
6 要點:
本節我們介紹了表達式樹在.NET面向對象程序設計中的作用、表達式樹的創建與解析,相信小伙伴們對表達式樹這種結構比較了解了。
表達式樹(Expression Tree)就是一種使用對象的方式來描述表達式。這也正是.NET一切皆是對象的思想體現。
下一節我們會介紹動態創建一個表達式樹結構、會舉列說明幾種表達式樹在.NET程序設計中的應用。
==============================================================================================
<如果對你有幫助,記得點一下推薦哦,如有有不明白或錯誤之處,請多交流>
<對本系列文章閱讀有困難的朋友,請先看《.net 面向對象編程基礎》>
<轉載聲明:技術需要共享精神,歡迎轉載本博客中的文章,但請注明版權及URL>
==============================================================================================