C# 2.0 引入匿名方法,C# 3.0 以 Lambda 運算式 (=>) 進一步簡化語法,並支援運算式樹 (Expression Tree) 奠基 LINQ。本文對比兩者語法、編譯器降級機制、變數捕獲語意與進階應用。
// C# 1.0 命名方法
btn.Click += new EventHandler(Btn_Click);
void Btn_Click(object s, EventArgs e) { BindData(); }
// C# 2.0 匿名方法
btn.Click += delegate(object s, EventArgs e) { BindData(); };
// C# 3.0 Lambda 運算式 (陳述式主體)
btn.Click += (s, e) => { BindData(); };
// C# 3.0 Lambda 運算式 (運算式主體) - 單一運算式隱含回傳
Func add = (x, y) => x + y;
<>c__DisplayClass0_0.b__0 ) + 顯示類別捕獲區域變數。this,靜態方法不捕獲。=> expr) 可轉換為 Expression<TDelegate> 建構運算式樹;陳述式主體 (=> { }) 僅能轉委派。
// 參數型別可省略 (編譯器推斷)
(x, y) => x + y
(int x, int y) => x + y
// 無參數
() => Console.WriteLine("Hi")
// 多行陳述式
(x, y) => { var z = x + y; return z; }
// 非同步 Lambda
async (token) => await DoWorkAsync(token)
var funcs = new List>();
for (int i = 0; i < 3; i++)
{
int captured = i; // C# 5.0+ 迴圈變數每輪新建,無需此行
funcs.Add(() => captured);
}
// C# 4.0 或舊版:全部輸出 3 (捕獲同一變數 i)
// C# 5.0+:輸出 0,1,2
C# 5.0 修正 foreach/for 迴圈變數捕獲語意,每輪迭代建立新變數副本。
Expression<Func x.Age > 18; 建構樹而非編譯委派。Func func = predicate.Compile(); -= 匿名委派)。