首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 3.0 Lambda 表達式:從匿名方法到函數式編程的進化

     編輯:關於C#

Lambda 表達式是 C# 3.0 引入的核心語法特性,它為委派建立、LINQ 查詢與函數式編程提供了簡潔有力的語法基礎。本文從匿名方法演進、語法細節、參數推斷、多參數、IL 等價性與實際應用場景深入解析。

從匿名方法到 Lambda

C# 2.0 匿名方法:


button.Click += delegate { listBox.Items.Add(textBox.Text); };

C# 3.0 Lambda 表達式:


button.Click += () => listBox.Items.Add(textBox.Text);

=> 讀作 "goes to",左側為參數清單,右側為運算式或陳述式區塊。

語法變體

形式範例說明
無參數() => 42參數清單為空括號
單一參數(隱式型別)x => x * 2括號可省略
單一參數(顯式型別)(int x) => x * 2需加括號
多參數(x, y) => x + y隱式型別推斷
多參數(顯式型別)(int x, string s) => s.Length + x
陳述式主體x => { Console.WriteLine(x); return x * 2; }需大括號與 return
運算式主體x => x * 2隱含回傳,無大括號

實際應用範例

集合篩選


List<string> list = new List<string> { "AA", "ABC", "DEFG", "XYZ" };

// 匿名方法
var evenAnon = list.FindAll(delegate(string s) { return s.Length % 2 == 0; });

// Lambda(單一參數隱式型別)
var evenLambda = list.FindAll(s => s.Length % 2 == 0);

多參數 Lambda 搭配擴充方法


Dictionary<string, int> clothes = new Dictionary<string, int> 
{ 
    { "Jeans", 20 }, { "Shirts", 15 }, { "Pajamas", 9 }, { "Shoes", 9 } 
};

// 擴充方法:依鍵值對篩選
public static Dictionary<K, V> FilterBy<K, V>(
    this Dictionary<K, V> dict, Func<K, V, bool> predicate)
{
    var result = new Dictionary<K, V>();
    foreach (var kvp in dict)
        if (predicate(kvp.Key, kvp.Value))
            result.Add(kvp.Key, kvp.Value);
    return result;
}

// 使用多參數 Lambda
var shortage = clothes.FilterBy((name, count) => name == "Shoes" && count < 10);
if (shortage.Count > 0) Console.WriteLine("We are short of shoes");

IL 等價性驗證

使用 ILDASM 對比匿名方法與 Lambda 產生的 IL,發現兩者幾乎完全相同:

  • 編譯器均產生編譯器生成的私有靜態方法(<Main>b__0)
  • 均快取委派實例(<>9__CachedAnonymousMethodDelegate1)
  • 執行語義無差異

結論:Lambda 表達式純粹為編譯期語法糖,不引入執行期新機制。

進階:運算式樹

Lambda 表達式賦值給 Expression<TDelegate> 時,編譯器產生運算式樹而非委派:


Func<int, int> func = x => x * 2;           // 委派:可執行程式碼
Expression<Func<int, int>> expr = x => x * 2; // 運算式樹:資料結構,可於執行時分析/修改/轉譯(如 LINQ to SQL)

這是 LINQ 提供者將查詢轉譯為 SQL 的關鍵基礎。

最佳實踐

  • ✅ 簡單投影/篩選/排序:優先使用 Lambda
  • ✅ 事件訂閱:button.Click += (s, e) => DoSomething();
  • ✅ 非同步延續:task.ContinueWith(t => HandleResult(t.Result))
  • ❌ 複雜邏輯:超過 3-5 行建議提煉為具名方法,提升可讀性與可測試性
  • ❌ 遞迴 Lambda:需配合 Func<T, TResult> 變數與 Y-Combinator,極難維護
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved