Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference in LINQ query results in .NET 3.5 and 4.5 [duplicate]

Tags:

c#

.net

linq

I executed the following code with C# 3.5 and 4.0. The results are entirely different.

    static void Main()
    {       
        int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        List<IEnumerable<int>> results = new List<IEnumerable<int>>();

        foreach (var num in numbers)
        {
            results.Add(numbers.Where(item => item > num));
        }

        foreach (var r in results)
        {
            Console.WriteLine("{0}", r.Count());
        }        
    }

With Microsoft (R) Visual C# 2008 Compiler version 3.5.30729.5420 the output is 0 0 0 0 0 0 0 0 0 0.

But with Microsoft (R) Visual C# Compiler version 4.0.30319.17929 the output is 9 8 7 6 5 4 3 2 1 0.

I have a faint idea that this is because of deferred execution or lazy evaluation but haven't clearly understood how it is responsible for different outputs here.

Correction: Sorry it was .NET 3.5 and 4.5 and also added compiler versions Please explain.

like image 706
mssrivatsa Avatar asked Sep 05 '13 15:09

mssrivatsa


2 Answers

Since c# 5, the loop variable in foreach is compiled such that it exists within the loop scope rather than outside it.

This means that when you close over the loop variable, you get different results.

Here's what Eric Lippert had to say about the original problem.

like image 128
spender Avatar answered Sep 30 '22 18:09

spender


You have accessed a variable inside a closure, therefore the results will differ on different versions of the compiler.

In C# 5.0, the variable is redefined in each iteration of the loop, whereas in previous C# versions it was only defined once.

For more info, see Eric Lippert's great blog post

More notably, the opening paragraph:

UPDATE: We are taking the breaking change. In C# 5, the loop variable of a foreach will be logically inside the loop, and therefore closures will close over a fresh copy of the variable each time. The "for" loop will not be changed. We return you now to our original article.

like image 32
mattytommo Avatar answered Sep 30 '22 16:09

mattytommo