| 版本 | 特性 | 語法範例 |
|---|---|---|
| C# 1.0/1.1 | 具名委派方法 | btn.Click += new EventHandler(Btn_Click); |
| C# 2.0 | 匿名方法 | btn.Click += delegate { list.Add(txt.Text); }; |
| C# 3.0 | Lambda 表達式 | btn.Click += (s, e) => list.Add(txt.Text); |
// 參數 => 運算式/語句區塊
x => x + 1 // 隱含型別,單一參數可省略括號
(int x) => x + 1 // 顯式型別
(x, y) => x * y // 多參數
() => Console.WriteLine("Hi") // 無參數
x => { var t = x * 2; return t; } // 語句區塊,需 return
Lambda 參數型別由上下文推論:
Func f1 = x => x + 1; // 推論 x 為 int
Func f2 = (x, y) => x + y; // 推論 x, y 為 int
var list = new List { "AA", "ABC", "DEFG", "XYZ" };
// 匿名方法 (C# 2.0)
var even1 = list.FindAll(delegate(string s) { return s.Length % 2 == 0; });
// Lambda (C# 3.0) - 更簡潔
var even2 = list.FindAll(s => s.Length % 2 == 0);
// 多參數 Lambda 搭配擴充方法
var clothes = new Dictionary
{
["Jeans"] = 20, ["Shirts"] = 15, ["Pajamas"] = 9, ["Shoes"] = 9
};
var shortage = clothes.FilterBy((name, count) => name == "Shoes" && count < 10);
// shortage 為 { ["Shoes", 9] }
FilterBy
public delegate bool KeyValueFilter(K key, V value);
public static class Extensions
{
public static Dictionary FilterBy(
this Dictionary dict, KeyValueFilter filter)
{
var result = new Dictionary();
foreach (var kvp in dict)
if (filter(kvp.Key, kvp.Value))
result.Add(kvp.Key, kvp.Value);
return result;
}
}
編譯器將兩者都降級為編譯器產生的私有方法 + 委派快取。IL 碼幾乎相同,Lambda 只是語法糖,執行效能無差異。
using System.Linq.Expressions;
Expression> expr = x => x > 5; // 編譯為 Expression Tree,而非 IL
// 可於執行時分析、修改、轉譯為 SQL (LINQ to SQL/EF 核心機制)
Func> asyncLambda = async () => {
await Task.Delay(100);
return 42;
};
var multipliers = new List>();
for (int i = 0; i < 3; i++)
{
int factor = i; // 每次迴圈新建變數,避免閉包陷阱
multipliers.Add(x => x * factor);
}
// multipliers[0](10) = 0, [1](10) = 10, [2](10) = 20
Expression<TDelegate>,單純執行用 Func/Action。Lambda 表達式是 C# 邁向函數式程式設計的關鍵一步,配合 LINQ、非同步程式設計、運算式樹,極大提升了程式碼表達力。從 delegate { } 到 () => { },不只是語法簡化,更是思維模式的升級。