Lambda表達式和表達式樹

一: Lambda表達式

首先,表達式的類型自己並不是委託類型,但它能夠經過多種方式隱式或者顯式地轉換成一個委託實例。匿名函數這個術語同時涵蓋了匿名方法和Lambda,不少狀況下二者可使用相互轉換原則。express

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,樹中的每一個節點自己都是一個表達式。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")); 
相關文章
相關標籤/搜索