0

Using .net 4.0, why does the following code print out 'one, two, three, four, five' rather than just printing out 'five' every time?

public void Go()
{
    List<Action> printActions = new List<Action>();
    String[] strings = new[] {"one", "two", "three", "four", "five"};

    foreach (String s in strings)
        printActions.Add(() => Console.WriteLine(s));

    foreach (Action printAction in printActions)
        printAction();
}

As far as I can tell, using older versions of .net, i should be running into the problem addressed here (using foreach variable in a closure), but in this case, the code appears to work.

Community
  • 1
  • 1
richzilla
  • 40,440
  • 14
  • 56
  • 86
  • Your `Add` statement creates a method object that encapsulates the passed parameter. Why would it print "five"? – Brandon Oct 21 '14 at 12:51
  • In .Net 4.0 they "fixed" `foreach` to capture the variable in the closure. – juharr Oct 21 '14 at 12:52
  • @Brandon, There is no parameter for it to encapsulate. It closes over the variable in the foreach statement. – richzilla Oct 21 '14 at 12:53
  • @Brandon Before .Net 4.0 the lambda would capture the variable used in the `foreach`, but that variable would change with each iteration thus resulting in the lambdas all having the same value. It was changed in .Net 4.0 because that is not what you would expect. – juharr Oct 21 '14 at 12:54
  • Read the whole answer to the question you linked to. It answers your question. – Eric Lippert Oct 21 '14 at 12:55
  • @EricLippert, id missed the bit about the compiler. Just tried using an old compiler, and it does indeed do what i expected. – richzilla Oct 21 '14 at 12:58

1 Answers1

2

.Net 4.0 is irrelevant here. Only thing is the c# compiler. Starting from C# 5.0 behavior is changed. I presume you're using C# 5.0 compiler.

This means that even in .Net 2.0 this code will work if you're using Visual studio 2012 (given that default C# compiler version is 5.0)

If you're using Visual studio 2012 or newer version by default C#5.0 compiler will be used and hence you don't see the bug.

Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189