了解 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中文网其他相关文章!