Little Difference between c#4 and c#5 compiler

What is the difference between outside declared variable and inside declared variable?

Case1:

Outside:

var i_ = default(int);

foreach (var i in new[] { 0, 1, 2, 3, 4, 5 })

{

i_ = i;

Console.WriteLine(i_);

}

Inside:

foreach (var i in new[]{0,1,2,3,4,5})

{

var i_= i;

Console.WriteLine(i_);

}

In this example the difference is only how the compiler allocate the variables, if the variable declared outside the loop the compiler need to allocate the i_ variable only once, and if  i_ declared inside the loop then for each iteration the compiler need to allocate new variable. But the expected output in this case is same: 0 1 2 3 4 5.

Case2:

Outside:

var fis = new List<Action>();

var i_ = default(int);

foreach (var i in new[]{0,1,2,3,4,5})

{

i_ = i;

fis.Add(() => Console.WriteLine(i_));

}

foreach (var fi in fis)

{

fi();

}

Inside:

var fis = new List<Action>();

foreach (var i in new[] { 0, 1, 2, 3, 4, 5 })

{

var i_ = i;

fis.Add(() => Console.WriteLine(i_));

}

foreach (var fi in fis)

{

fi();

}

In case 2 we capture the loop variable i in closure and copy it into  the i_ variable.

then call the Console.Writeline function. In other words we deferred the print of i variable.

In this case the Outside scenario prints 5 5 5 5 5, and Inside scenario prints the expected result 0,1,2,3,4,5.

But if we don’t care about outside or inside declarations and we write the function as:

var fis = new List<Action>();

foreach (var i in new[] { 0, 1, 2, 3, 4, 5 })

{

fis.Add(() => Console.WriteLine(i));

}

foreach (var fi in fis)

{

fi();

}

In C# 4 the result is like outside declared variable: 5,5,5,5,5.

And in C#5 the result is like inside declared variable : 0,1,2,3,4,5.

Iterate over For loop:

Outside:

var fis = new List<Action>();

//declaring the variable outside the loop

var i_ = new int();

for (i_ = 0; i_ < 5; i_++)

{

fis.Add(() => { Console.WriteLine(i_); });

}

foreach (var fi in fis) fi();

Inside:

var fis = new List<Action>();

for (int i = 0; i < 5; i++)

{

fis.Add(() => { Console.WriteLine(i); });

}

foreach (var fi in fis) fi();

If we iterate over the For loop, the compiler behavior is unchanged.  And the result of For loop examples above is the same : 5,5,5,5,5.

 

So if we want to get the expected result we need to capture the variable inside the loop.

var fis = new List<Action>();

for (int i = 0; i < 5; i++)

{

int i_ = i;

fis.Add(() => { Console.WriteLine(i_); });

}

foreach (var fi in fis) fi();

In this case the result will be 0,1,2,3,4.

Advertisements

About Idan Reuven

Idan is Microsoft Certified Proffesional Developer (MCPD) Idan Working As Senior Software developer. and specialize in professional application development with WPF, WCF, Entity Framework, XAML, HTML 5, Java Script , jQuery, MVC, MVVM, C#, C++, SQL Server Technologies.
This entry was posted in C# 5. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s