LINQ查询的差异导致.NET 3.5和4.5

mss*_*tsa 8 .net c# linq

我用C#3.5和4.0执行了以下代码.结果完全不同.

    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());
        }        
    }
Run Code Online (Sandbox Code Playgroud)

使用Microsoft(R)Visual C#2008编译器版本3.5.30729.5420,输出为0 0 0 0 0 0 0 0 0 0.

但是使用Microsoft(R)Visual C#Compiler版本4.0.30319.17929输出9 8 7 6 5 4 3 2 1 0.

我有一个微弱的想法,这是因为延迟执行或延迟评估,但还没有清楚地理解它是如何负责不同的输出在这里.

更正:对不起,它是.NET 3.5和4.5,还添加了编译器版本 请解释.

spe*_*der 7

从c#5开始,循环变量in foreach被编译为使其存在于循环范围内而不是在它之外.

这意味着当您关闭循环变量时,会得到不同的结果.

以下是Eric Lippert对原始问题所说的话.

  • 这是自C#5.0以来,而不是.NET 4.0. (6认同)

mat*_*mmo 6

您已在闭包内访问了一个变量,因此不同版本的编译器的结果会有所不同.

在C#5.0中,变量在循环的每次迭代中被重新定义,而在之前的C#版本中,它仅被定义一次.

有关更多信息,请参阅Eric Lippert的精彩博文

更值得注意的是,开头段落:

更新:我们正在进行重大改变.在C#5中,foreach的循环变量将在逻辑上位于循环内部,因此闭包每次都会关闭变量的新副本."for"循环不会改变.我们现在回复您的原始文章.

  • @ AlessandroD'Andria那是因为你正在使用C#5.0编译器.使用的.NET版本无关紧要. (2认同)