了解 C# Lambda 表達式變數擷取
C# lambda 表達式提供了定義匿名函數的緊湊方法。 然而,它們與周圍範圍內的變數的交互作用可能很棘手。
問題:共享變數修改
讓我們來看看一個常見問題。 以下程式碼旨在建立一個操作列表,每個操作列印不同的計數器值:
<code class="language-csharp">List<Action> actions = new List<Action>(); for (int i = 0; i < 10; i++) { actions.Add(() => Console.WriteLine(i)); } foreach (Action a in actions) a();</code>
令人驚訝的是,這印了「10」十次。 lambda 捕獲對 的 引用 i
,而不是它的值。 當循環修改 i
時,所有 lambda 都會看到最終值。
解:按值擷取
C# 並不像 C 0x 的 [=]
那樣直接支援以值擷取語法。 解決方法是在循環範圍內建立本機副本:
<code class="language-csharp">for (int i = 0; i < 10; i++) { int copy = i; // Create a local copy actions.Add(() => Console.WriteLine(copy)); }</code>
現在,每個 lambda 捕獲一個單獨的 copy
變量,為每次迭代保留正確的值。
為什麼本地副本很重要
差別在於變數作用域。 引用共享相同的記憶體位置;變化會立即反映出來。 副本在擷取 時建立變數值 的獨立快照。 對原始變數的後續變更與 lambda 捕獲的副本無關。
以上是在 C# Lambda 表達式中擷取變數時如何防止意外行為?的詳細內容。更多資訊請關注PHP中文網其他相關文章!