Created
February 11, 2012 13:13
-
-
Save joshpeterson/1799362 to your computer and use it in GitHub Desktop.
Storing iterator state in a collection can have unexpected consequences.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
namespace UnexpectedLoop | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
// MyCollection stores its iterator state in the collection, so does not work as expected. | |
Console.WriteLine("MyCollection:"); | |
MyCollection mine = new MyCollection(); | |
PrintValues(mine); | |
// List<int> stores its iterator state in a separate class and | |
// creates a new instance of that class for each GetEnumerator call. | |
Console.WriteLine("List<int>:"); | |
List<int> theirs = new List<int>(new int[] { 7 }); | |
PrintValues(theirs); | |
} | |
static void PrintValues(IEnumerable<int> values) | |
{ | |
bool numberOfValuesDisplayed = false; | |
foreach (int value in values) | |
{ | |
// Use LINQ to enumerate the collection again! | |
if (!numberOfValuesDisplayed) | |
{ | |
Console.WriteLine("The collection has this many values: {0}", values.Count()); | |
numberOfValuesDisplayed = true; | |
} | |
Console.WriteLine("{0}", value); | |
} | |
} | |
// Based on the example IEnumerator implementation on MSDN: | |
// http://msdn.microsoft.com/en-us/library/system.collections.ienumerator.aspx | |
class MyCollection : IEnumerable<int>, IEnumerator<int> | |
{ | |
int[] values = new int[1]{7}; | |
int position = -1; | |
public IEnumerator<int> GetEnumerator() | |
{ | |
return this; | |
} | |
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() | |
{ | |
return this; | |
} | |
public int Current | |
{ | |
get { return values[position]; } | |
} | |
public void Dispose() | |
{ | |
} | |
object System.Collections.IEnumerator.Current | |
{ | |
get { return (object)values[position]; } | |
} | |
public bool MoveNext() | |
{ | |
position++; | |
return position < values.Length; | |
} | |
public void Reset() | |
{ | |
position = -1; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment