首先,表達式的類型自己並不是委託類型,但它能夠經過多種方式隱式或者顯式地轉換成一個委託實例。匿名函數這個術語同時涵蓋了匿名方法和Lambda,不少狀況下二者可使用相互轉換原則。express
Func<string, int> returnlength = delegate(string text) { return text.Length; };
Func<string, int> returnlength = (string text) => { return text.Length; };
Func<string, int> returnlength = (string text) => text.Length;
Func<string, int> returnlength = (text) => text.Length;
一: 表達式樹函數
1.1基本知識性能
表達式樹提供了一種抽象的方式將一些代碼表示成一個對象樹,表達式樹主要用於LINQ,樹中的每一個節點自己都是一個表達式。spa
不一樣的表達式類型表明能在代碼中執行的不一樣操做:二元操做,一元操做,方法調用,構造函數調用等等。code
System.Linq.Expressions命名空間包含了表明表達式的各個類,它們都繼承自Expression,一個抽象的主要包含一些靜態工廠方法的類,這些方法用於建立其餘表達式類的實例,然而,Expression類也包括兩個屬性。對象
1.Type屬性表明表達式求值後的.NET類型,可把它視爲一個返回類型。例如一個表達式要獲取一個字符串的Length屬性,該表達式的類型就是int。blog
2.NodeType屬性返回所表明的表達式的種類。它是ExpressionType枚舉的成員,包括LessThan、Multiply和Invoke等。仍然使用上面的例子,對於myString.Length這個屬性訪問來講,其節點類型是MemberAccess。。繼承
而且該屬性能區分由相同的類表示的不一樣種類的表達式。ip
示例以下:字符串
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"));