foreach关于指针类型数组的闭包语义

Jep*_*sen 11 c# foreach closures pointers c#-5.0

在C#5中,foreach语句的闭包语义(当迭代变量被匿名函数"捕获"或"关闭"时)发生了着名的变化(链接到该主题的线程).

问题:是否打算更改指针类型数组?

为什么我想问的原因是,一个的"扩张" foreach的语句已被改写,由于技术原因(我们不能使用Current的财产System.Collections.IEnumerator,因为该物业已声明的类型object是不兼容的指针类型)相比foreach于其他藏品.C#语言规范中的相关部分,"指针数组",在5.0版本中说:

foreach (V v in x) EMBEDDED-STATEMENT
Run Code Online (Sandbox Code Playgroud)

扩展到:

{
  T[,,…,] a = x;
  V v;
  for (int i0 = a.GetLowerBound(0); i0 <= a.GetUpperBound(0); i0++)
  for (int i1 = a.GetLowerBound(1); i1 <= a.GetUpperBound(1); i1++)
  …
  for (int in = a.GetLowerBound(N); iN <= a.GetUpperBound(n); iN++) {
    v = (V)a.GetValue(i0,i1,…,iN);
    EMBEDDED-STATEMENT
  }
}
Run Code Online (Sandbox Code Playgroud)

我们注意到声明V v;在所有for循环之外.因此看起来闭包语义仍然是"旧的"C#4风格,"循环变量被重用,循环变量相对于循环变为"外部".

为了说明我在说什么,请考虑这个完整的C#5计划:

using System;
using System.Collections.Generic;

static class Program
{
  unsafe static void Main()
  {
    char* zeroCharPointer = null;
    char*[] arrayOfPointers =
      { zeroCharPointer, zeroCharPointer + 1, zeroCharPointer + 2, zeroCharPointer + 100, };

    var list = new List<Action>();

    // foreach through pointer array, capture each foreach variable 'pointer' in a lambda
    foreach (var pointer in arrayOfPointers)
      list.Add(() => Console.WriteLine("Pointer address is {0:X2}.", (long)pointer));

    Console.WriteLine("List complete");
    // invoke those delegates
    foreach (var act in list)
      act();
  }

  // Possible output:
  //
  // List complete
  // Pointer address is 00.
  // Pointer address is 02.
  // Pointer address is 04.
  // Pointer address is C8.
  //
  // Or:
  //
  // List complete
  // Pointer address is C8.
  // Pointer address is C8.
  // Pointer address is C8.
  // Pointer address is C8.
}
Run Code Online (Sandbox Code Playgroud)

那么上述程序的正确输出是什么?

Yuv*_*kov 10

我已经联系了C#语言PM的Mads Torgersen,似乎他们只是忘了更新规范的这一部分.他的确切答案是(我问为什么规范没有更新):

因为我忘记了!:-)我现在有最新的草案,并提交给ECMA.谢谢!

所以看起来C#-5的行为对于指针数组也是相同的,这就是为什么你看到第一个输出,这是正确的输出.