如果我在C#中写了一个foreach循环:
foreach(String a in veryComplicatedFunction())
{
}
它会在每次迭代中计算veryComplicatedFunction吗?还是只会计算一次并将结果存储在某个地方?
如果我在C#中写了一个foreach循环:
foreach(String a in veryComplicatedFunction())
{
}
它会在每次迭代中计算veryComplicatedFunction吗?还是只会计算一次并将结果存储在某个地方?
你的问题在规范的12.9.5章节中得到了回答,其中提到:
foreach (V v in x) embedded-statement
{
E e = ((C)(x)).GetEnumerator();
try {
V v;
while (e.MoveNext()) {
v = (V)(T)e.Current;
embedded-statement
}
}
finally {
… // Dispose e
}
}
如您所见,在这个展开式中,表达式x只被计算一次。
它只会计算一次
这要看你所说的“一次”是什么意思。如果你有以下方法:
public static IEnumerable<int> veryComplicatedFunction()
{
List<string> l = new List<string> { "1", "2", "3" };
foreach (var item in l)
{
yield return item;
}
}
每次yield后,控制权都会返回到调用veryComplicatedFunction方法的位置。因此,如果它们共享List l,则可能会出现一些奇怪的结果。消除这种问题的可靠方法是在veryComplicatedFunction上调用ToArray扩展。
veryComplicatedFunction
很可能返回 IEnumerable<string>
,这意味着它的计算只会执行一次,并以某种方式流式传输结果。然而,没有看到实际方法,无法保证它的作用。可以保证的是 veryComplicatedFunction
只被调用一次,foreach
遍历方法的返回值。它应该只计算一次。另外,非常复杂的函数(verycomplicatedfunction())必须返回一个 IEnumerable
或者 IEnumerable<T>
或者任何拥有公共 GetEnumerator() 方法的对象。