術語“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運算式並不意味著使用操作符的左側。