重现捕获迭代变量问题

时间:2015-03-10 10:50:44

标签: c# closures c#-5.0

我正在重读Nutshell中关于捕获迭代变量(页138)的c#5.0的一部分,我试图在c#4.0和c#5.0上重现下面的代码,但是直到现在还没有希望找到差异

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(); 
    }
}

注意 我有Visual Studio 2012(安装了.net 4.0和4.5),我在尝试重现问题时更改了目标框架

更新 为了解释更多问题,c#4.0的输出将与c#5.0不同 我知道由于更新了最新版本的C#Compiler

,这可能没什么用处

任何人都可以告诉我如何重现这个问题吗?

3 个答案:

答案 0 :(得分:4)

您无法重现它,因为您正在更改.Net框架的版本而不是编译器。您始终使用C#v5.0修复了foreach循环的问题。您可以通过for循环查看问题:

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();

要使用旧的编译器,您需要一个旧的VS版本。在这种情况下,要查看您的代码中断foreach,您需要在VS 2010中测试它(我在本地做过)。


您可能想尝试更改编译器的语言版本(如注释中建议的xanatos)但不使用旧的编译器。它使用相同的编译器,但限制您使用特定功能:

  

由于C#编译器的每个版本都包含语言规范的扩展,因此/langversion不会为您提供早期版本编译器的等效功能。

来自/langversion (C# Compiler Options)

答案 1 :(得分:3)

由于此问题已在C#编译器5.0中修复,因此无法使用Visual Studio 2012重现它。

您需要使用C#编译器版本4.0来重现作者试图解释的问题。使用Visual Studio 2010,您可以重现该问题。

即使您在Vs2012中更改了语言版本,它仍然无法正常工作。因为you're still using the C# 5.0 compiler

答案 2 :(得分:0)

自4.0以来foreach循环已更改此行为。但您可以使用for循环重现它:

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(); 
}

输出:“333333”