-4

From the book C# in Depth

static void Main()
{
    // First build a list of actions
    List<Action> actions = new List<Action>();
    for (int counter = 0; counter < 10; counter++)
    {
        actions.Add(() => Console.WriteLine(counter));
    }

    // Then execute them
    foreach (Action action in actions)
    {
        action();
    }
} 

this will print 10 10 10...

static void Main()
{
    // First build a list of actions
    List<Action> actions = new List<Action>();
    for (int counter = 0; counter < 10; counter++)
    {
        int copy = counter;
        actions.Add(() => Console.WriteLine(copy));
    }

    // Then execute them
    foreach (Action action in actions)
    {
        action();
    }
} 

this will print 10 9 8 ..

I dont understand why

Captain Comic
  • 15,744
  • 43
  • 110
  • 148
  • The second code block will not print what you claim, but "0, 1, 2, ..." instead. Relevant terms are "closure" and "capture", which I'm quite certain the book will explain either before or after the example code. See also the duplicate, which answers your question. – CodeCaster Nov 19 '16 at 14:52
  • it does not http://csharpindepth.com/Articles/Chapter5/Closures.aspx – Captain Comic Nov 19 '16 at 14:52
  • @CaptainComic I though you was reading the actual book – Zein Makki Nov 19 '16 at 14:54
  • Are you sure the second prints 10 9 8, and not 0 1 2... 9? – Jon Hanna Nov 19 '16 at 14:55
  • @JonHanna sorry of course – Captain Comic Nov 19 '16 at 14:56
  • Bottom line, local variables captured in closures are compiled as compiler generated class members (members of reference types).. So when actions are executed, all actions point to the same values while in the second case, you take a local copy for each value (So multiple values are captured) – Zein Makki Nov 19 '16 at 14:57

1 Answers1

0

The expression uses a variable, counter or copy depending on which piece of code above is used, that is defined outside of the expression, so it is captured by the delegate.

In the first example, the same counter is captured by them all, and at the time they are invoked that variable has the value 10, so they all print that.

In the second a separate variable is created each time, and that is captured by the delegate. Since nothing changes the value of copy after that, they each have different values from 0 to 9.

Jon Hanna
  • 110,372
  • 10
  • 146
  • 251