可能重复:
How does foreach work when looping through function results?
如果我具有以下功能 - 将在foreach循环中为每次迭代调用ReturnParts(),还是只调用一次?
private void PrintParts()
{
foreach(string part in ReturnParts())
{
// Do Something or other.
}
}
private string[] ReturnParts()
{
// Build up and return an array.
}
答案 0 :(得分:30)
它只会被调用一次。
P.S。多次调用它没有多大意义。如果您希望每次结果都不同,您可以每次重新调用它。你会如何迭代不断变化的集合?
答案 1 :(得分:19)
您可以通过在函数“ReturnParts”上放置一个断点来自行确定。如果每次迭代都达到多次,那么肯定是。
答案 2 :(得分:9)
它只会被调用一次。
The foreach
loop is equivalent to the following code:
IEnumerable<string> enumerator = (collection).GetEnumerator();
try {
while (enumerator.MoveNext()) {
string part = (string)enumerator.Current;
// Do Something or other.
}
} finally {
IDisposable disposable = enumerator as System.IDisposable;
if (disposable != null) disposable.Dispose();
}
答案 3 :(得分:7)
想知道几周前for,foreach,while和goto之间的差异所以我写了这个测试代码。所有方法都将编译到相同的IL中(除了foreach版本上的变量名之外)。在调试模式下,一些NOP语句将处于不同的位置。
static void @for<T>(IEnumerable<T> input)
{
T item;
using (var e = input.GetEnumerator())
for (; e.MoveNext(); )
{
item = e.Current;
Console.WriteLine(item);
}
}
static void @foreach<T>(IEnumerable<T> input)
{
foreach (var item in input)
Console.WriteLine(item);
}
static void @while<T>(IEnumerable<T> input)
{
T item;
using (var e = input.GetEnumerator())
while (e.MoveNext())
{
item = e.Current;
Console.WriteLine(item);
}
}
static void @goto<T>(IEnumerable<T> input)
{
T item;
using (var e = input.GetEnumerator())
{
goto check;
top:
item = e.Current;
Console.WriteLine(item);
check:
if (e.MoveNext())
goto top;
}
}
static void @gotoTry<T>(IEnumerable<T> input)
{
T item;
var e = input.GetEnumerator();
try
{
goto check;
top:
item = e.Current;
Console.WriteLine(item);
check:
if (e.MoveNext())
goto top;
}
finally
{
if (e != null)
e.Dispose();
}
}
Per @ Eric的评论......
我已使用通用数组扩展了for
,while
,'goto'和foreach
。现在for each
语句看起来使用数组的索引器。对象数组和字符串以类似的方式扩展。对象将删除在方法调用Console.WriteLine之前发生的装箱,并且字符串将分别用T item
和T[] copy...
替换char item
和string copy...
。请注意,不再需要临界区,因为不再使用一次性枚举器。
static void @for<T>(T[] input)
{
T item;
T[] copy = input;
for (int i = 0; i < copy.Length; i++)
{
item = copy[i];
Console.WriteLine(item);
}
}
static void @foreach<T>(T[] input)
{
foreach (var item in input)
Console.WriteLine(item);
}
static void @while<T>(T[] input)
{
T item;
T[] copy = input;
int i = 0;
while (i < copy.Length)
{
item = copy[i];
Console.WriteLine(item);
i++;
}
}
static void @goto<T>(T[] input)
{
T item;
T[] copy = input;
int i = 0;
goto check;
top:
item = copy[i];
Console.WriteLine(item);
i++;
check:
if (i < copy.Length)
goto top;
}