Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Question regarding IEnumerable and IEnumerator

I use the following code to enable myClass to use foreach. But I am rather new to programming and have some difficulty in understanding the following code. I described my problems in the comments. I would be grateful for providing some information.

    public class MyClass : IEnumerable<string> 
    {  
    //1) What is IEnumerator for?
        // Whats the difference between IEnumerator and IEnumerable
    public IEnumerator<string> GetEnumerator()     
    {
             yield return "first";         
             yield return "second";     
    }      
    //2) What is it for?  It just calls above method 
   IEnumerator IEnumerable.GetEnumerator()
         {
             return GetEnumerator(); 
         } 
    }
   //3) Lastly what benefits I have from implementing genetic interface 
   //IEnumerable<string> instead of just IEnumerable
like image 869
Grant Smith Avatar asked Dec 28 '10 18:12

Grant Smith


People also ask

What is the difference between IEnumerator and IEnumerable?

An IEnumerator is a thing that can enumerate: it has the Current property and the MoveNext and Reset methods (which in . NET code you probably won't call explicitly, though you could). An IEnumerable is a thing that can be enumerated...which simply means that it has a GetEnumerator method that returns an IEnumerator .

Why do we need IEnumerable?

IEnumerable interface is used when we want to iterate among our classes using a foreach loop. The IEnumerable interface has one method, GetEnumerator, that returns an IEnumerator interface that helps us to iterate among the class using the foreach loop.

What is IEnumerable and what significance does it hold?

What is IEnumerable in C#? IEnumerable in C# is an interface that defines one method, GetEnumerator which returns an IEnumerator interface. This allows readonly access to a collection then a collection that implements IEnumerable can be used with a for-each statement.

Is IEnumerable immutable?

Just realized IEnumerable is immutable, what are other commonly used immutable generic interfaces?


1 Answers

What is the difference between IEnumerator and IEnumerable?

Jason's answer is good but I thought I'd just add how I think about this. Imagine you have a sequence:

1, 1, 2, 3, 5, 8, 13, ...

Now imagine you have an arrow pointing at some position of that sequence:

1, 1, 2, 3, 5, 8, 13, ...
         ^

An "arrow" is an object that can do two things. First, it can give you the thing it is pointing at. Second, it can make itself point at the next thing.

IEnumerator is an arrow. It has a property, Current, that gives you the thing it is pointing at. It has a method, MoveNext() that makes itself point at the next thing.

How do you get an arrow in the first place? You need an arrow factory. You ask the factory for an arrow, and it gives you an arrow that points to the first element in the sequence.

IEnumerable is an arrow factory. It has a method, GetEnumerator, that gives you an arrow to the first element of the sequence.

A nice property of this scheme is that you can have multiple arrows pointing to different places in the same sequence.

what are the benefits of implementing generic interface IEnumerable instead of just IEnumerable?

Suppose the sequence is of integers. If you implement IEnumerable then when you say

foreach(int x in mysequence)

what that will actually do is convert the int in the sequence to object, boxing the integer, and then immediately unbox the object back to integer, adding a completely unnecessary memory allocation to every single operation. If the compiler knows that the sequence is of integers then it can skip the unnecessary boxing operation.

Suppose the sequence is of strings. If you implement IEnumerable<string> then you can say:

string first = mysequence.First();

If you don't, then you have to say

string first = (string)mysequence.First();

which is unnecessary and error-prone. Rather than instruct the compiler via a cast that the type is string, you can simply guarantee that the type is string by using the type system.

like image 194
Eric Lippert Avatar answered Oct 05 '22 22:10

Eric Lippert