Understanding C# Lambda Expression Variable Capture in Loops
A frequent problem in C# programming involves lambda expressions within loops. The way lambda expressions capture variables can lead to unexpected results. Let's explore this issue and its solution.
Consider this code:
<code class="language-csharp">List<Func<int>> actions = new List<Func<int>>(); int variable = 0; while (variable < 10) { actions.Add(() => variable * 2); ++variable; } foreach (var act in actions) { Console.WriteLine(act.Invoke()); }</code>
The expected output is a sequence of even numbers (0, 2, 4, 6, 8). However, the actual output is five 10s. This happens because each lambda expression captures a reference to the variable
, not its value at the time of its creation. By the time the lambdas are invoked, variable
has already reached its final value of 10.
The Solution: Creating a Copy
To correct this, we need to create a copy of the loop variable within the scope of each lambda expression:
<code class="language-csharp">List<Func<int>> actions = new List<Func<int>>(); int variable = 0; while (variable < 10) { int copy = variable; // Create a copy of the variable actions.Add(() => copy * 2); ++variable; } foreach (var act in actions) { Console.WriteLine(act.Invoke()); }</code>
Now, each lambda expression captures its own independent copy of variable
's value at the time of its creation, producing the expected output.
C# 5 and Foreach Loops
It's important to note that this behavior is less of a concern with foreach
loops in C# 5 and later versions. The compiler handles the variable capture differently in foreach
to prevent this issue. However, the explicit copy method remains a best practice for clarity and compatibility with older C# versions. Using this approach ensures consistent behavior across all C# versions and loop types.
The above is the detailed content of Why Do C# Lambda Expressions in Loops Capture the Final Variable Value, and How Can This Be Fixed?. For more information, please follow other related articles on the PHP Chinese website!