位置:首頁 > 其他技術 > LinQ教學 > LINQ Lambda表達式

LINQ Lambda表達式

術語“Lambda表達式'是來自於”拉姆達“演算這又是施加用於定義功能的數學符號及其名稱。 lambda表達式作為LINQ式的可執行部分轉換的方式在運行時的邏輯,因此它可以傳遞到數據源方便。但是,lambda表達式不僅僅局限於查找應用LINQ而已。

這些表達式由下麵的語法表示:

(輸入參數) => 表達式或語句塊

下麵是lambda表達式的一個例子

y => y * y

上述表達式指定一個參數y和y的值的平方。然而,這是不可能的到這種形式來執行一個lambda表達式。在C#中的lambda表達式的例子如下所示。

C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace lambdaexample
{
  class Program
  {
     delegate int del(int i);
     static void Main(string[] args)
     {
        del myDelegate = y => y * y;
        int j = myDelegate(5);
        Console.WriteLine(j);
        Console.ReadLine();
     }
  }
}

VB

Module Module1
  Private Delegate Function del(ByVal i As Integer) As Integer
  Sub Main(ByVal args As String())
     Dim myDelegate As del = Function(y) y * y
     Dim j As Integer = myDelegate(5)
     Console.WriteLine(j)
     Console.ReadLine()
  End Sub
End Module

當C#或VB的上述代碼被編譯和執行時,它產生了以下結果:

25

表達Lambda

如在lambda表達式的上麵所示的語法表達是在右手側,這些也被稱為lambda表達式。

異步Lambdas

通過使用異步關鍵字結合異步處理創建lambda表達式被稱為異步lambda表達式。下麵是異步lambda的一個例子。

Func<Task<string>> getWordAsync = async() => hello”;

Lambda的標準查詢操作

查詢運算符內的lambda表達通過在需要時相同的評估計算,並不斷地作用於各輸入序列中的元素,而不是整個序列。 開發人員允許Lambda表達式到自己的邏輯轉換成標準查詢操作.在下麵的例子中,開發人員使用的“Where”運算符,通過利用lambda表達式的回收,從給出的列表中奇數值。

C#

//Get the average of the odd Fibonacci numbers in the series... 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace lambdaexample
{
  class Program
  {     
     static void Main(string[] args)
     {
        int[] fibNum = { 1, 1, 2, 3, 5, 8, 13, 21, 34 };
        double averageValue = fibNum.Where(num => num % 2 == 1).Average();
        Console.WriteLine(averageValue);
        Console.ReadLine();
     }
  }
}

VB

Module Module1
  Sub Main()
     Dim fibNum As Integer() = {1, 1, 2, 3, 5, 8, 13, 21, 34}
     Dim averageValue As Double = fibNum.Where(Function(num) num Mod 2 = 1).Average()
     Console.WriteLine(averageValue)
     Console.ReadLine()
  End Sub
End Module

讓我們編譯和運行上麵的程序,這將產生以下結果:

7.33333333333333

lambda類型推斷

在C#中,類型推斷方便地用於各種情況,而且也冇有明確指定的類型。但是如果一個lambda表達式,類型推斷將工作必須滿足在已指定每種類型為編譯器。讓我們考慮下麵的例子。

delegate int Transformer (int i);

這裡,編譯器采用的類型推理時的事實,x是一個整數,這是通過檢查所述變壓器的參數類型進行繪製。

Lambda表達式變量的作用域

有而這樣的lambda表達式內發起變量的lambda表達式,使用變量的作用域並不意味著是可見的外部方法有一些規則。還有一個規則,一個捕獲變量不是被垃圾回收,除非委托引用相同變得符合垃圾收集的行為。此外,還有禁止lambda表達式中的return語句導致返回封閉方法的規則。

這裡有一個例子,以證明lambda表達式變量的作用域。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace lambdaexample
{
  class Program
  {
     delegate bool D();
     delegate bool D2(int i);

     class Test
     {
        D del;
        D2 del2;
        public void TestMethod(int input)
        {
           int j = 0;
           // Initialize the delegates with lambda expressions.
           // Note access to 2 outer variables.
           // del will be invoked within this method.
           del = () => { j = 10; return j > input; };

           // del2 will be invoked after TestMethod goes out of scope.
           del2 = (x) => { return x == j; };

           // Demonstrate value of j:            
           // The delegate has not been invoked yet.
           Console.WriteLine("j = {0}", j);        // Invoke the delegate.
           bool boolResult = del();
           
           Console.WriteLine("j = {0}. b = {1}", j, boolResult);
        }

        static void Main()
        {
           Test test = new Test();
           test.TestMethod(5);

           // Prove that del2 still has a copy of
           // local variable j from TestMethod.
           bool result = test.del2(10);
           
           Console.WriteLine(result);

           Console.ReadKey();
        }
     }
  }
}

讓我們編譯和運行上麵的程序,這將產生以下結果:

j = 0
j = 10. b = True
True

表達式樹

Lambda表達式中使用表達式樹結構廣泛。表達式樹放棄代碼中的數據結構類似於樹,其中每個節點本身是一樣的方法調用的表達,或者可以是一個二進製運算如x<y,下麵是lambda表達式的使用用於構造一個表達式樹的一個例子。

LAMBDA語句

還有lambda表達式由兩個或三個語句,但不僅在構造表達式樹中。 return語句必須寫在lambda語句。

lambda聲明的語法

(params) => {statements}

lambda的聲明示例

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace lambdaexample
{
  class Program
  {
     static void Main(string[] args)
     {
        int[] source = new[] { 3, 8, 4, 6, 1, 7, 9, 2, 4, 8 };

        foreach (int i in source.Where(
                 x =>
                 {
                    if (x <= 3)
                       return true;
                    else if (x >= 7)
                       return true;
                    return false;
                 }
                ))
        Console.WriteLine(i);
        Console.ReadLine();
     }
  }
}

讓我們編譯和運行上麵的程序,這將產生以下結果:

3
8
1
7
9
2
8

lambda表達式被用作基於方法的LINQ查詢參數,並決不允許有一個地方對操作的左側像是或者就像匿名方法。 雖然,Lambda表達式何其相似匿名方法,這些根本不是限製被用來作為唯一表示。

使用lambda表達式要點要記住

  • lambda表達式可以返回一個值,並可以帶有參數。
  • 參數可以用不同的方式使用lambda表達式無數的定義。
  • 如果在一個lambda表達式單獨的語句,就冇有必要花括號,而如果有多個語句,大括號以及返回值都是寫必不可少的。
  • 隨著lambda表達式,可以通過被稱為閉合的特征來訪問變量lambda表達式塊的存在之外。利用閉合的應謹慎,以避免任何問題。
  • 這是不執行任何lambda表達式中的任何不安全的代碼。
  • lambda表達式並不意味著使用操作符的左側。