重现捕获迭代变量问题

本文关键字:变量 问题 迭代 | 更新日期: 2024-11-07 16:38:02

我正在 Nutshell 中重读 c# 5.0 中关于捕获迭代变量的部分(第 138 页),我试图在 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# 编译器

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

重现捕获迭代变量问题

您无法重现它,因为您正在更改 .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# 编译器选项)

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

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

即使您在 Vs2012 中更改了语言版本,它仍然不起作用。 因为你仍在使用 C# 5.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"