What is Yenumerable and Yenumerator for?

Asked

Viewed 4,792 times

9

I made a combo of questions about IEnumerable and IEnumerator not only to help me but to help everyone who needs a more didactic explanation.

Question 1

Could someone explain in a more didactic way what these are for interfaces and what advantages they bring to iterations that a "simple loop" does not bring?

Question 2

Since Ienumerable has only one method that calls Ienumerator and that to iterate a collection we are not obligatory to implement Ienumerable, follows a question: What is Ienumerable’s relationship with Ienumerator?

Question 3

Can someone explain to me why this code works even though it’s not the most commonly taught codes for implementing Ienumerator?

//IEnumerator
      int[] array = new int[]{1, 2, 3, 4, 5 }; 
      IEnumerator o = array.GetEnumerator();
      while (o.MoveNext())
      {
        Console.WriteLine(o.Current);    
      } 

About the foreach relationship with Ienumerator/Ienumerable

You can get a lot of information here.

2 answers

4


Could someone explain in a more didactic way what these interfaces are for

IEnumerable is an interface that marks the classes that wish to implement it so that it is known that it can be iterated through an iterator. Obviously this should only be used on objects that are data sequences, otherwise it makes no sense to iterate there. The method is used to obtain the iterator. Most of the times the implementation of this method is the same or very similar.

Whenever implementing the IEnumerable will have to implement, somehow, in the class or elsewhere the interface IEnumerator.

The iterator is defined by the interface IEnumerator which proposes to have the necessary mechanism to iterate, ie need a state with the current object (Current), what is the next item on the list (MoveNext()) and how to restart iterator scanning (Reset()).

what advantages they bring to iterations that a "simple loop" does not bring?

If the language does not determine how to loop a data sequence, the only way you can create a type that is an iterable data sequence is by providing a mechanism that says:

  • how to take the dice
  • the next and
  • how to start over.

Your type should provide the code that does this properly and if possible with the best possible performance for your case. In this case the language does in array and string, so in theory these types would not need to have these interfaces, but they have for use in other situations that the language does not control.

Considering that Ienumerable only has one method that calls the Ienumerator and that to iterate a collection we do not have the obligation to implement the Ienumerable, it follows a question: What is the relationship of Ienumerable with the Ienumerator?

That’s not quite true. It’s even possible in most cases not to implement the IEnumerable in a collection, but a lot of things will not be possible to be made. Nor can we consider it a collection, at least not an eternal one. It will be a beautiful one of a gambiarra. It has collection that simply is not possible to iterate without doing something totally out of the pattern. And the purpose of these interfaces is to maintain a standard way of doing things.

Can anyone explain to me why this code works even though the codes are not most commonly taught to implement Ienumerator?

The code works because that’s what it has to do.

  • he picks up the iterator and throws it at an object
  • the MoveNext() takes the next element of the sequence, in case you should take the first
  • accesses the element inside the loop
  • check if you have the next item to decide whether to continue or not, since the MoveNext() returns a boolean.

Exactly how this works internally is specific iterator problem, is implementation detail.

Actually this code is not good because it leaks memory leaving the iterator alive even after finishing its use. In other situations it is possible that a cast is necessary to use the element since it returns a object, unless you use a IEnumerator<T> which allows you to return the real type of the object. All this the compiler puts to you, so it is better to use the foreach than doing at hand, the compiler knows what he’s doing, the programmer doesn’t always.

The foreach can only work on objects that have the interface IEnumerable since it needs to iterate in the data sequence.

In the link provided in the question actually has how the code gets after compiled (it is made a Lowering).

If the . NET were written today it would be different, perhaps the idea by Jared Parsons is the implementation, which is much better than the adopted.

4

In the Question 3 I believe that by virtue of arrays already implement the "factory Ienumerable" we can "instantiate" the enumerator through the method array.GetEnumerator() and its consequent attribution to the object IEnumerator o.

We must take into account, that the use of Ienumerator in this case is only as a purpose of study because it is very clear that the best iteration practice for the example is to use a "simple loop" ( for/while or even foreach).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.