Distinction between iterator and enumerator
Iterating means repeating some steps, while enumerating means going through all values in a collection of values. So enumerating usually requires some form of iteration.
In that way, enumerating is a special case of iterating where the step is getting a value from a collection.
Note the "usually" – enumerating may also be performed recursively, but recursion and iteration are so closely related that I would not care about this small difference.
You may also enumerate values you do not explicitly store in a collection. For example, you can enumerate the natural number, primes, or whatever but you would calculate these values during the enumeration and not retrieve them from a physical collection. You understand this case as enumerating a virtual collection with its values defined by some logic.
I assume Reed Copsey got the point. In C# there are two major ways to enumerate something.
- Implement
Enumerable
and a class implementingIEnumerator
- Implement an iterator with the
yield
statement
The first way is harder to implement and uses objects for enumerating. The second way is easier to implement and uses continuations.
What C# calls an iterator is more commonly (outside of the C# world) called a generator or generator function (e.g. in Python). A generator function is a specialized case of coroutine. A C# iterator (generator) is a special form of an enumerator (a data type implementing the IEnumerable
interface).
I dislike this usage of the term iterator for a C# generator because it is just as much an enumerator as it is an iterator. Too late for Microsoft to change its mind though.
For contrast consider that in C++ an iterator is a value which is used primarily to access sequential elements in a collection. It can be advanced, derferenced to retrieve a value, and tested to see whether the end of the collection has been reached.
In C# 2+, iterators are a way for the compiler to automatically generate the IEnumerable and/or IEnumerable<T> interfaces for you.
Without iterators, you would need to create a class implementing IEnumerator, including Current, MoveNext, and Reset. This requires a fair amount of work. Normally, you would create a private class that implemtented IEnumerator<T> for your type, then yourClass.GetEnumerator() would construct that private class, and return it.
Iterators are a way for the compiler to automatically generate this for you, using a simple syntax (yield). This lets you implement GetEnumerator() directly in your class, without a second class (The IEnumerator) being specified by you. The construction of that class, with all of its members, is done for you.
Iterators are very developer friendly - things are done in a very efficient way, with much less effort.
When you use foreach, the two will behave identically (provided you write your custom IEnumerator correctly). Iterators just make life much simpler.