如果我有一个如下所示的循环:
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)
初始化也只发生一次.
如果您查看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的答案.