'Unexpected result when looping over List<Action>
I'm currently looking for tricky interview snippets and I found two that I cannot explain. I merged them together so they can be run at the same time.
Here is the code:
using System.Collections.Generic;
public class Program
{
public static void Main(string[] args)
{
var intActions = new List<Action>();
for (int i = 0; i < 4; i++)
intActions.Add(() => { Console.WriteLine(i); });
foreach (var action in intActions)
action();
string[] strings = { "abc", "def", "ghi" };
var stringActions = new List<Action>();
foreach (string str in strings)
stringActions.Add(() => { Console.WriteLine(str); });
foreach (var action in stringActions)
action();
}
}
The output is:
4
4
4
4
abc
def
ghi
Can anyone explain me why is the result like this? I'd expect four "4"s with four "ghi"s or "0123" and "abc def ghi"
Solution 1:[1]
The reason why you are seeing 4444 and not 0123, & ghi ghi ghi instead of abc def ghi is due to closures.
The i variable passed to the delegate is passed by reference and not by value which means that all of the actions will point to the same memory location for variable i & the latest value for i (set to 4 on the last iteration of the loop).
For the output to be 0123, copying the variable to another temp variable would mean each action would have a pointer to a separate memory location, and thus yield the numbers as 'expected'.
var intActions = new List<Action>();
for (int i = 0; i < 4; i++) {
int copy = i;
intActions.Add(() => { Console.WriteLine(copy); });
}
foreach (var action in intActions)
action();
The same concept applies to the second part of your example:
string[] strings = { "abc", "def", "ghi" };
var stringActions = new List<Action>();
foreach (string str in strings) {
var copy = str;
stringActions.Add(() => { Console.WriteLine(copy); });
}
foreach (var action in stringActions)
action();
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
