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