What is the difference between IEnumerator and IEnumerable?
Jason's answer is good, but I thought I would just add how I think about it. Imagine you have a sequence:
1, 1, 2, 3, 5, 8, 13, ...
Now imagine that you have an arrow pointing to some position in this sequence:
1, 1, 2, 3, 5, 8, 13, ... ^
An arrow is an object that can do two things. First, he can give you what he points to. Secondly, he may indicate the following.
IEnumerator is an arrow. It has a Current property that gives you what it points to. It has a MoveNext () method that points to the following.
How do you get the arrow in the first place? You will need a factory arrow. You ask factory for the arrow, and it gives an arrow pointing to the first element in the sequence.
IEnumerable is a factory arrow. It has a GetEnumerator method that gives you an arrow to the first element of a sequence.
A good feature of this scheme is that you can have multiple arrows pointing to different places in the same sequence.
What are the benefits of implementing the universal IEnumerable interface, not just IEnumerable?
Suppose a sequence has integers. If you implement IEnumerable , then when you say
foreach(int x in mysequence)
what you really need to do is convert the int into a sequence into an object, an integer box, and then immediately return the object back to an integer, adding completely unnecessary memory allocation for each individual operation. If the compiler knows that the sequence has integers, then it may skip the unnecessary boxing operation.
Suppose a sequence has strings. If you implement IEnumerable<string> then you can say:
string first = mysequence.First();
If you do not, you must say
string first = (string)mysequence.First();
which is not necessary and error prone. Instead of instructing the compiler by casting that the type is a string, you can simply ensure that the type is a string using a type system.