Lambda 表達式源自匿名方法演進。MSDN 雜誌文章指出:若 Lambda 優先引入語言,匿名方法將不再需要。本節深入探討 Lambda 的變數捕獲(Lifting/Closure)機制。
List<Func<int>> list = new List<Func<int>>();
for (int i = 0; i < 3; i++)
{
list.Add(() => i); // 捕獲變數 i 本身,而非當時的值
}
foreach (var func in list)
{
Console.WriteLine(func()); // 輸出:3, 3, 3 (非預期的 0, 1, 2)
}
原因:Lambda 捕獲的是變數 i,而非迴圈當下的值。迴圈結束時 i=3,所有委派共享同一個 i,故均回傳 3。
for (int i = 0; i < 3; i++)
{
int captured = i; // 每次迴圈建立新區域變數
list.Add(() => captured);
}
// 輸出:0, 1, 2
這是 C# 5.0 以前的標準解法;C# 5.0+ 對 foreach 迴圈變數語意調整,但 for 迴圈仍需注意。