C # - Is a function called for each iteration of the foreach loop?

Possible duplicate:
How does foreach work when looping through a function?

If I have functionality like the following: will it return ReturnParts () for each iteration in the foreach loop, or will it be called only once?

private void PrintParts() { foreach(string part in ReturnParts()) { // Do Something or other. } } private string[] ReturnParts() { // Build up and return an array. } 
+18
syntax c #
Mar 15 '10 at 13:47
source share
4 answers

It will be called only once.

PS Calling him several times would make little sense. You will call it again each time if you expect the result to be different every time. And how would you sort out an ever-changing set?

+25
Mar 15 '10 at 13:49
source share

You can determine this yourself by setting a breakpoint on the Return Parts function. If it has several times for each iteration, then yes.

+17
Mar 15 '10 at 13:49
source share

It will be called only once.

The foreach 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(); } 
+9
Mar 15 '10 at 13:49
source share

Thinking about the differences between foreach, while and goto a few weeks ago, I wrote this test code. All methods will be compiled into the same IL (the other is the variable name in the foreach version). In debug mode, several NOP statements will be in different positions.

 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(); } } 

For the comment by @Eric ...

I have extended for , while , 'goto' and foreach with shared arrays. The for each statement now uses a pointer to an array. Arrays of objects and strings expand similarly. Objects will remove the box that occurs before the method is called in Console.WriteLine and Strings will replace T item and T[] copy... with char item and string copy... respectively. Note that the critical section is no longer needed because the one-time counter is no longer used.

 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; } 
+6
Mar 15 '10 at 14:01
source share



All Articles