一、Lambda 表達式
1. 概念 Lambda 表達式是一種匿名函數(無名稱的函數),簡化了委托和匿名方法的寫法,格式為: (參數列表) => 表達式或語句塊
它可以作為參數傳遞,或賦值給委托類型變量。
2. 基本語法與簡寫規則
形式 | 說明 | 示例 |
---|---|---|
完整形式 | 帶參數類型、大括號和 return | (int a, int b) => { return a + b; } |
省略參數類型 | 編譯器自動推斷參數類型 | (a, b) => { return a + b; } |
單參數省略括號 | 只有一個參數時,可省略() | a => { return a * 2; } |
單表達式省略大括號 | 函數體只有一句表達式時,省略{} 和return | a => a * 2 (自動返回結果) |
3. 應用場景
作為委托參數傳遞(如集合查詢、事件處理)
簡化匿名方法的編寫
配合
Func
/Action
等內置委托使用
示例:集合查詢
int[] numbers = { 19, 20, 3, 18, 30 }; // 查找第一個偶數(使用Lambda作為查詢條件) int firstEven = Array.Find(numbers, v => v % 2 == 0);
4. 與托的關聯 Lambda 表達式需賦值給委托類型變量(如Func
/Action
)才能調用:
// Func<參數類型, 返回值類型>:帶返回值的委托 Func<int, int, int> add = (a, b) => a + b; int result = add(2, 3); // 結果:5 ? // Action<參數類型>:無返回值的委托 Action<string> print = msg => Console.WriteLine(msg); print("Hello Lambda"); // 輸出:Hello Lambda
二、事件(Event)
1. 概念 事件是一種特殊的多播委托,用于實現發布 - 訂閱模式,允許對象在特定行為發生時通知其他對象。
發布者:定義事件并觸發它的類
訂閱者:注冊事件并提供處理方法的類
2. 核心特性
基于委托實現,通常使用
EventHandler
或EventHandler<TEventArgs>
只能在聲明它的類內部觸發(調用
Invoke
)外部只能通過
+=
(訂閱)和-=
(取消訂閱)操作本質是 “安全的委托”,防止外部隨意修改或觸發
3. 基本用法
步驟 | 代碼示例 |
---|---|
定義事件 | public event EventHandler MyEvent; |
訂閱事件 | MyEvent += EventHandlerMethod; (可綁定命名方法、匿名委托或 Lambda) |
觸發事件 | MyEvent?.Invoke(sender, e); (需先檢查是否有訂閱者) |
4. 事件處理程序的簽名 必須與事件委托的簽名匹配(以EventHandler
為例):
// 方法參數:事件源(sender)和事件數據(e) void EventHandlerMethod(object sender, EventArgs e) {// 處理邏輯 }
5. 多播特性 一個事件可以綁定多個處理方法,觸發時按綁定順序依次執行:
// 綁定多個處理方法 MyEvent += Method1; MyEvent += Method2; MyEvent += (s, e) => Console.WriteLine("Lambda處理"); ? // 觸發時依次執行Method1 → Method2 → Lambda表達式 MyEvent?.Invoke(this, EventArgs.Empty);
三、Lambda 與事件的結合使用
Lambda 表達式可簡化事件處理程序的綁定:
// 定義事件 public event EventHandler ButtonClick; ? // 使用Lambda綁定事件處理 ButtonClick += (sender, e) => {Console.WriteLine("按鈕被點擊了"); }; ? // 觸發事件 ButtonClick?.Invoke(this, EventArgs.Empty);
總結
Lambda 表達式:簡化匿名函數的編寫,常用于簡化委托參數,配合
Func
/Action
使用。事件:基于委托的發布 - 訂閱機制,提供安全的跨對象通信,外部只能訂閱 / 取消訂閱,內部觸發。
兩者結合:使用 Lambda 可快速編寫事件處理邏輯,減少代碼冗余。
以下是 C# 中 Lambda 表達式的常見用法和示例表格,涵蓋基本語法、場景及說明:
類型 | 語法格式 | 示例代碼 | 說明 |
---|---|---|---|
無參數 | () => 表達式 | () => Console.WriteLine("Hello") | 無輸入參數,執行單一表達式或語句塊 |
單參數 | 參數 => 表達式 | x => x * 2 | 單個參數可省略括號,表達式返回計算結果 |
多參數 | (參數1, 參數2) => 表達式 | (a, b) => a + b | 多個參數需用括號包裹,用逗號分隔 |
語句塊 | 參數 => { 語句; } | n => { if (n > 0) return "正"; else return "負"; } | 復雜邏輯需用{} 包裹,需顯式使用return 返回值 |
委托匹配 | 與委托簽名一致 | Func<int, bool> isEven = x => x % 2 == 0; | 匹配Func<int, bool> 委托(輸入 int,返回 bool) |
事件處理 | 簡化事件訂閱 | button.Click += (s, e) => Console.WriteLine("Clicked"); | 替代傳統的事件處理方法,簡化代碼 |
LINQ 篩選 | 結合Where 方法 | var adults = people.Where(p => p.Age >= 18); | 在 LINQ 中用于定義篩選條件,p 代表集合中的每個元素 |
LINQ 投影 | 結合Select 方法 | var names = people.Select(p => p.Name); | 提取元素的特定屬性,轉換為新的序列 |
排序條件 | 結合OrderBy 方法 | var sorted = numbers.OrderBy(n => n); | 定義排序依據,此處按元素本身升序排序 |
匿名類型創建 | 生成匿名對象 | people.Select(p => new { p.Name, AgeGroup = p.Age / 10 * 10 }) | 在 LINQ 中創建匿名類型,包含指定字段(如Name 和AgeGroup ) |
閉包捕獲變量 | 訪問外部變量 | int threshold = 10; var filtered = list.Where(x => x > threshold); | 可訪問 Lambda 表達式外部的變量(threshold ),形成閉包 |
異步 Lambda | 結合async/await | async () => await HttpClient.GetAsync("https://example.com") | 用async 修飾,內部可使用await ,返回Task 或Task<T> |
關鍵特性說明:
簡潔性:相比匿名方法,語法更簡潔,省略了
delegate
關鍵字和參數類型(編譯器自動推斷)。類型推斷:參數類型通常可省略,編譯器會根據上下文(如委托類型、LINQ 方法)自動推斷。
不可變性:Lambda 表達式本身是匿名函數,無法直接調用,需賦值給委托類型(如
Func
、Action
)或作為方法參數傳遞。閉包特性:能捕獲并訪問外部作用域的變量,變量的生命周期會被延長至 Lambda 表達式使用完畢。
適用場景:主要用于簡化委托調用、事件處理、LINQ 查詢、異步操作等場景,減少代碼冗余。