在C#5中是否改变了foreach对变量的使用?

a_h*_*din 37 c# foreach c#-5.0 .net-4.5

在这个答案中,https: //stackoverflow.com/a/8649429/1497 Eric Lippert说"我们很有可能在下一版本的C#中解决这个问题;对于开发人员而言,这是一个主要的痛点". foreach循环使用变量.

在下一个版本中,每次运行"foreach"循环时,我们将生成一个新的循环变量,而不是每次都关闭相同的变量.这是一个"突破"的变化,但在绝大多数情况下,"休息"将是修复而不是导致错误.

我无法找到任何表明此更改尚未完成的内容.有没有迹象表明这是foreach循环在C#5中的工作方式?

Jef*_*tes 55

这是对C#语言的改变,而不是.NET框架.因此,它只影响在C#5.0下编译的代码,而不管该代码将在哪个.NET框架版本上执行.

C#5.0

规范的第8.8.4节明确表示已进行了此更改.具体来说,C#5.0规范的第249页指出:

foreach (V v in x) embedded-statement
Run Code Online (Sandbox Code Playgroud)

然后扩展到:

{
    E e = ((C)(x)).GetEnumerator();
    try {
        while (e.MoveNext()) {
            V v = (V)(T)e.Current;
            embedded-statement
        }
    }
    finally {
        … // Dispose e
    }
}
Run Code Online (Sandbox Code Playgroud)

然后:

在while循环中放置v对于嵌入式语句中发生的任何匿名函数如何捕获它很重要.

C#4.0

当与C#4.0规范进行比较时,对规范的这种更改是明确的(再次,在第8.8.4节中,但这次,第247页):

foreach (V v in x) embedded-statement
Run Code Online (Sandbox Code Playgroud)

然后扩展到:

{
    E e = ((C)(x)).GetEnumerator();
    try {
        V v;
        while (e.MoveNext()) {
            v = (V)(T)e.Current;
            embedded-statement
        }
    }
    finally {
        … // Dispose e
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,变量v在循环外而不是在内部声明,就像在C#5.0中一样.

注意

您可以在Visual Studio的安装文件夹中找到C#规范VC#\Specifications\1033.这是VS2005,VS2008,VS2010和VS2012的情况,使您可以访问C#1.2,2.0,3.0,4.0和5.0的规范.您也可以通过搜索找到MSDN上的规范C# Specification.

  • 一个例子就是好的:`List <Action> list = new List <Action>(); foreach(var in new int [] {1,2,3,4,5}){list.Add(()=> Console.WriteLine(i)); } foreach(列表中的var f){f(); }` (6认同)
  • 我不确定这里是否需要一个例子,因为OP已经理解了正在讨论的问题,并且只是在寻找变更的确认. (4认同)
  • 那就是说,谢谢发帖.对于需要上下文的这个问题的未来观众,我可以看到它的价值.也许它可以以某种方式编辑而不会混淆事物.谢谢. (3认同)