C# Tip Article
foreach creates new iterator for IEnumerable
In C#, foreach statement provides a convenient way of iterating an enumerable object. foreach iterates an element in an enumerable object one by one.
But then, a question popped up. What happens when we use "foreach" multiple times against the same enumerable object? Below is a sample code that used foreach twice.
In the first foreach (in Print() method), I intentionally added a "break" statement to break out of the loop after displaying first element. In the second foreach, it iterates all of the elements.
So the question is "will the 2nd foreach continue from the previous iteration point (which is from 2nd element of data) OR will it start over again from the 1st element?"
class Program { static void Main(string[] args) { var n = GetNumber(); Print(n); } static void Print(IEnumerabledata) { // 1st foreach against IEnumerable foreach (var item in data) { Console.WriteLine(item); break; } // 2nd foreach against the same IEnumerable foreach (var item in data) { Console.WriteLine(item); } } static IEnumerable GetNumber() { yield return 1; yield return 2; yield return 3; } }
The correct answer is every "foreach" will restart the iteration all over again. So the result of the above code will be "1 1 2 3" instead of "1 2 3."
foreach gets new enumerator from the IEnumerable object every time it starts loop. This behavior is little different from Python. If you run the below Python program, you will get "1 2 3" since "for" statement in Python is using current iterator instead of creating new iterator.
def getNumber(): yield 1 yield 2 yield 3 def printData(data): for n in data: print(n) break for n in data: print(n) g = getNumber() printData(g)