I'm rereading a part from c# 5.0 in Nutshell about the capturing iteration variables (Page 138) and I have tried to reproduce the code bellow on c# 4.0 and c# 5.0 but with no hope to catch the difference until now
using System;
class Test
{
static void Main()
{
Action[] actions = new Action[3];
int i = 0;
foreach (char c in "abc")
actions[i++] = () => Console.Write(c);
for (int j = 0; j < 3; j++)
{
actions[j]();
}
foreach (Action a in actions) a();
Console.ReadLine();
}
}
Note
I have Visual studio 2012(.net 4.0 and 4.5 installed) and I have changed the target framework while trying to reproduce the issue
Update
to explain more the issue the output with c# 4.0 will be different from c# 5.0
I Know this may be less useful due to update to a recent version of C# Compiler
can anyone enlighten me on how to reproduce this issue ?
You can't reproduce it because you are changing the version of the .Net framework but not the compiler. You're always using C# v5.0 which fixes the issue for foreach
loops. You can see the issue with for
loops though:
Action[] actions = new Action[3];
int i = 0;
for (int j = 0; j < "abc".Length; j++)
actions[i++] = () => Console.Write("abc"[j]);
for (int j = 0; j < 3; j++)
{
actions[j]();
}
foreach (Action a in actions) a();
Console.ReadLine();
To use the old compiler you need an old VS version. In this case to see your code break with foreach
you need to test it in VS 2010 (I did locally).
You might want to try to change the language version of the compiler (as xanatos suggested in the comments) but that doesn't use an old compiler. It uses the same compiler but limits you to using specific features:
Because each version of the C# compiler contains extensions to the language specification, /langversion
does not give you the equivalent functionality of an earlier version of the compiler.
From /langversion (C# Compiler Options)
Because this issue has been fixed in C# compiler 5.0, you can't reproduce it with Visual studio 2012.
You need to use the C# compiler version 4.0 to reproduce the issue which author is trying to explain. With Visual studio 2010 you can reproduce the problem.
Even if you change the Language version in Vs2012, it still won't work. because you're still using the C# 5.0 compiler.
This behavior had been changed for foreach
loops since 4.0. But you can reproduce it with a for
loop:
static void Main()
{
Action[] actions = new Action[3];
int i = 0;
for (var c = 0; c < 3; c++)
actions[i++] = () => Console.Write(c);
for (int j = 0; j < 3; j++)
{
actions[j]();
}
foreach (Action a in actions) a();
Console.ReadLine();
}
Output: "333333"