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

Has foreach's use of variables been changed in C# 5?

在这个答案中,https://stackoverflow.com/a/8649429/1497-eric lippert说,"仅供参考,我们很可能在下一个版本的c中解决这个问题,这是开发人员在foreach循环如何使用变量方面的一个主要难点"。

In the next version each time you run through the"foreach" loop we will generate a new loop variable rather than closing over the same variable every time. This is a"breaking" change but in the vast majority of cases the"break" will be fixing rather than causing bugs.

我还没有找到任何迹象表明这一变化已经发生。是否有任何迹象表明这是foreach循环在C 5中的工作方式?


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

C 5

本规范第8.8.4节明确说明已进行了此项变更。具体来说,C 5.0规范第249页规定:

1
foreach (V v in x) embedded-statement

is then expanded to:

1
2
3
4
5
6
7
8
9
10
11
12
{
    E e = ((C)(x)).GetEnumerator();
    try {
        while (e.MoveNext()) {
            V v = (V)(T)e.Current;
            embedded-statement
        }
    }
    finally {
        … // Dispose e
    }
}

后来:

The placement of v inside the while loop is important for how it is
captured by any anonymous function occurring in the
embedded-statement.

C 4

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

1
foreach (V v in x) embedded-statement

is then expanded to:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
    E e = ((C)(x)).GetEnumerator();
    try {
        V v;
        while (e.MoveNext()) {
            v = (V)(T)e.Current;
            embedded-statement
        }
    }
    finally {
        … // Dispose e
    }
}

注意变量v是在循环外部而不是在循环内部声明的,就像C 5.0那样。

注释

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