How does foreach work when passing through a function?

Suppose I have the following code:

foreach(string str in someObj.GetMyStrings()) { // do some stuff } 

Will someObj.GetMyStrings() be called on each iteration of the loop? It would be better to do the following:

 List<string> myStrings = someObj.GetMyStrings(); foreach(string str in myStrings) { // do some stuff } 

?

+28
c # foreach
Oct. 27 '09 at 18:36
source share
4 answers

A function called only once returns IEnumerator<T> ; after that, the MoveNext() method and the Current property are used to repeat the results:

 foreach (Foo f in GetFoos()) { // Do stuff } 

somewhat equivalent:

 using (IEnumerator<Foo> iterator = GetFoos().GetEnumerator()) { while (iterator.MoveNext()) { Foo f = iterator.Current; // Do stuff } } 

Note that the iterator is located at the end - this is especially important for allocating resources from iterator blocks, for example:

 public IEnumerable<string> GetLines(string file) { using (TextReader reader = File.OpenText(file)) { string line; while ((line = reader.ReadLine()) != null) { yield return line; } } } 

In the above code, you really want the file to be closed when you finish the iteration, and the compiler implements IDisposable cunningly to make this work.

+45
Oct 27 '09 at 19:25
source share

No. the function will be called once to get IEnumerable .., and then call MoveNext and Current again.

+18
Oct 27 '09 at 18:39
source share

GetMyStrings () migrates an object of type IEnumerable. The runtime knows how to deal with this. It calls IEnumerable.GetEnumerator (), and then this enumerator object calls MoveNext () and Current.

+3
Oct 27 '09 at 18:41
source share

Just to round out the question if you find yourself in "all for the same"; for (int x = 0; x <ProvideCeiling (); x ++) calls the function every time.

0
Nov 09 '17 at 8:39 on
source share



All Articles