Lambda表达式和表达式树
首先,表達式的類型本身并非委托類型,但它可以通過多種方式隱式或者顯式地轉換成一個委托實例。匿名函數這個術語同時涵蓋了匿名方法和Lambda,很多情況下兩者可以使用相互轉換原則。
1.用匿名方法創建委托實例。? ? ? ? ? ? ? ? ? ? ? Func<string, int> returnlength = delegate(string text) { return text.Length; }; 對照的直接用lambda形式實現上述方法,代碼如下: Func<string, int> returnlength = (string text) => { return text.Length; }; 等同于 Func<string, int> returnlength = (string text) => text.Length; 或者 Func<string, int> returnlength = (text) => text.Length; 在閱讀lanbda表達式時,可以將 => 部分看成 ”goes to“。?一: 表達式樹
1.1基本知識
表達式樹提供了一種抽象的方式將一些代碼表示成一個對象樹,表達式樹主要用于LINQ,樹中的每個節點本身都是一個表達式。
不同的表達式類型代表能在代碼中執行的不同操作:二元操作,一元操作,方法調用,構造函數調用等等。
System.Linq.Expressions命名空間包含了代表表達式的各個類,它們都繼承自Expression,一個抽象的主要包含一些靜態工廠方法的類,這些方法用于創建其他表達式類的實例,然而,Expression類也包括兩個屬性。
1.Type屬性代表表達式求值后的.NET類型,可把它視為一個返回類型。例如一個表達式要獲取一個字符串的Length屬性,該表達式的類型就是int。
2.NodeType屬性返回所代表的表達式的種類。它是ExpressionType枚舉的成員,包括LessThan、Multiply和Invoke等。仍然使用上面的例子,對于myString.Length這個屬性訪問來說,其節點類型是MemberAccess。。
并且該屬性能區分由相同的類表示的不同種類的表達式。
示例如下:
Expression first = Expression.Constant(2);Expression second = Expression.Constant(3);Expression add = Expression.Add(first, second);? ? ? Func<int> acmpiled = Expression.Lambda<Func<int>>(add).Compile(); ? //編譯成可執行的委托方法。
Debug.Write(add);該代碼會產生輸出“(2+3)”,這意味著這些表達式樹類覆蓋了ToString來產生可讀的輸出。
注意:“葉”表達式在代碼中是最先創建的,我們需要自上而下構建這些表達式。
1.2表達式樹與委托
LambdaExpression是從Expression派生的類型之一,泛型類?Expression<TDelegate>又是從LambdaExpression派生的。Expression與?Expression<TDelegate>的區別在于:泛型類以靜態類型的方法標識了它是什么種類的表達式,也就是說,他確定了返回類型和參數。所以顯然,TDelegate必須是一個委托類型。
注意:并非所有的Lambda表達式都能轉換成表達式樹。不能將帶有一個語句塊(即使只有一個return語句)的Lambda轉換成表達式樹,只有對單個表達式進行求值的lambda才可以。表達式中不能包含賦值操作,因為在表達式中表示不了這種操作。
示例二如下:
Expression<Func<string, string, bool>> expression = (x, y) => x.StartsWith(y);Func<string, string, bool> complied = expression.Compile();Debug.Write(complied("first", "second"));Debug.Write(complied("first", "fir"));示例二等同于如下代碼:
//構造調用方法的各個組件MethodInfo method = typeof(string).GetMethod("StartsWith", new[] { typeof(string) }); //方法ParameterExpression target= Expression.Parameter(typeof(string), "x"); //方法主var methodArg = Expression.Parameter(typeof(string), "y"); //參數Expression[] methodArgs = new [] { methodArg }; //參數列表MethodCallExpression call = Expression.Call(target, method, methodArgs); //從以上組件創建CallExpression//將call轉換為lambda表達式ParameterExpression[] lambdaParameters = new[] { target, methodArg }; //參數var lambda = Expression.Lambda<Func<string, string, bool>>(call, lambdaParameters);Func<string, string, bool> complied = lambda.Compile();Debug.Write(complied("first", "second"));Debug.Write(complied("first", "fir"));?
轉載于:https://www.cnblogs.com/caoheyang911016/p/4272574.html
總結
以上是生活随笔為你收集整理的Lambda表达式和表达式树的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux下c++實現簡單的生產者消費者
- 下一篇: 在Linux上编译安装php开发环境(i