C#循环:遍历数组

hau*_*ous 15 c# loops

如果我有一个如下所示的循环:

foreach (string pass in new string[] { "pass1", "pass2", "pass3" })
{
 x = pass; //etc
}
Run Code Online (Sandbox Code Playgroud)

匿名字符串数组最初是创建一次,还是每次传递都重新创建一次?

我相信前者,但同事们确信这是一个等待发生的错误,因为他们说foreach循环的每次迭代都会导致创建一个新的字符串数组.

VS反汇编代码表明我是对的,但我想确定.

我们正在考虑这个问题的原因是试图理解一个神秘的错误,它报告了一个集合在迭代时已被更改.

Ser*_*kiy 27

根据Eric Lippert博客规范,foreach循环是一个语法糖:

{
  IEnumerator<string> e = ((IEnumerable<string>)new string[] { "pass1", "pass2", "pass3" }).GetEnumerator();
   try
   { 
     string pass; // OUTSIDE THE ACTUAL LOOP
      while(e.MoveNext())
      {
        pass = (string)e.Current;
        x = pass;
      }
   }
   finally
   { 
      if (e != null) ((IDisposable)e).Dispose();
   }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,枚举器是在循环之前创建的.

@Rawling正确指出,该数组通过编译器处理有点不同.Foreach循环优化带有数组的for循环.根据C#的内部结构,您的C#5代码将如下所示:

string[] tempArray;
string[] array = new string[] { "pass1", "pass2", "pass3" };
tempArray = array;

for (string counter = 0; counter < tempArray.Length; counter++)
{
    string pass = tempArray[counter];
    x = pass;
}
Run Code Online (Sandbox Code Playgroud)

初始化也只发生一次.

  • +1从C#5.0开始,变量`pass`将在循环内. (4认同)
  • 我认为这对于一个数组来说是微妙的不同......它不会将一个`foreach`循环变成一个`for`循环吗? (4认同)

Raw*_*ing 5

如果您查看ILSpy,此代码将被翻译成类似的内容

string[] array = new string[]
{
    "pass1",
    "pass2",
    "pass3"
};
for (int i = 0; i < array.Length; i++)
{
    string pass = array[i];
}
Run Code Online (Sandbox Code Playgroud)

所以是的,数组只创建一次.

但是,说服你的同事的最佳参考可能是C#规范的第8.8.4节,它基本上会告诉你LazyBerezovsky的答案.