I wrote a program designed to create a randomish list of numbers from a given starting point. It was a quick a dirty thing but I found an interesting effect when playing with it that I don't quite understand.
void Main() { List<int> foo = new List<int>(){1,2,3}; IEnumerable<int> bar = GetNumbers(foo); for (int i = 1; i < 3; i++) { foo = new List<int>(){1,2,3}; var wibble = GetNumbers(foo); bar = bar.Concat(wibble); } Iterate(bar); Iterate(bar); } public void Iterate(IEnumerable<int> numbers) { Console.WriteLine("iterating"); foreach(int number in numbers) { Console.WriteLine(number); } } public IEnumerable<int> GetNumbers(List<int> input) { //This function originally did more but this is a cutdown version for testing. while (input.Count>0) { int returnvalue = input[0]; input.Remove(input[0]); yield return returnvalue; } } The output of runing this is:
iterating 1 2 3 1 2 3 1 2 3 iterating That is to say the second time I iterate through bar immediately after it is empty.
I assume this is something to do with the fact that the first time I iterate that it empties the lists that are being used to generate the list and subsequently it is using these same lists that are now empty to iterate.
My confusion is on why this is happening? Why do my IEnumerables not start from their default state each time I enumerate over them? Can somebody explain what exactly I'm doing here?
And to be clear I know that I can solve this problem by adding a .ToList() to my call to GetNumbers() which forces immediate evaluation and storage of the results.