CSharp - What is the output: Capturing iteration variables

Question

What is the output from the following code

using System;
class MainClass
{
   public static void Main(string[] args)
   {
      Action[] actions = new Action[3];
      for (int i = 0; i < 3; i++){
          actions [i] = () => Console.Write (i);
      }
      foreach (Action a in actions) {
         a();
      }
   }
}


Click to view the answer

333
The following program writes 333 instead of writing 012:

Note

When you capture the iteration variable of a for loop, C# treats that variable as though it was declared outside the loop.

This means that the same variable is captured in each iteration.

We can illustrate this better by expanding the for loop as follows:

Demo

using System;
class MainClass// www  .  java 2 s.com
{
   public static void Main(string[] args)
   {
      Action[] actions = new Action[3];
      int i = 0;
      actions[0] = () => Console.Write (i);
      i = 1;
      actions[1] = () => Console.Write (i);
      i = 2;
      actions[2] = () => Console.Write (i);
      i = 3;
      foreach (Action a in actions) a();    // 333
   }
}

Result

To output 012, assign the iteration variable to a local variable that's scoped inside the loop:

Demo

using System;
class MainClass//from  w w  w . j a va 2s .  c o  m
{
   public static void Main(string[] args)
   {

      Action[] actions = new Action[3];
      for (int i = 0; i < 3; i++)
      {
       int my = i;
       actions [i] = () => Console.Write (my);
      }
      foreach (Action a in actions) a();     // 012
   }
}

Result

Because my is freshly created on every iteration, each closure captures a different variable.

Related Topic