了解 Lambda 表達式中迭代變數的意外行為
一位開發人員最近遇到了有關在 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 action in actions) { action(); }</code>
人們可能會期望它按順序列印數字 0 到 9。 相反,它打印“10”十次。 這是因為 lambda 表達式不會為每次迭代捕獲 的 副本 i
。 相反,它們捕獲對變數的引用i
。 當 foreach
循環執行時,循環已完成,並且 i
保持其最終值 10。因此,每個 lambda 表達式都會列印此最終值。
這種意想不到的結果強調了避免這種編碼模式的重要性。 編譯器警告是重要的保障措施。 若要實現所需的順序輸出,請在迴圈內建立新變數並為其指派迭代變數的值:
<code class="language-csharp">List<Action> actions = new List<Action>(); for (int i = 0; i < 10; i++) { int j = i; // Capture a copy of i actions.Add(() => Console.WriteLine(j)); } foreach (Action action in actions) { action(); }</code>此修訂後的程式碼可以正確列印 0 到 9,因為每個 lambda 表達式現在都會擷取值
的唯一、獨立的副本。 這個簡單的變更可確保預期的一致行為。 j
以上是為什麼在 Lambda 表達式中使用迭代變數會導致意外結果?的詳細內容。更多資訊請關注PHP中文網其他相關文章!