2

I had started learning iterator methods and implementation of IEnumerators in c#. I got confused at a point regarding the yield return statement.

Suppose, I create an iterator method 'Iterator()' and I have a collection 'myCollection' containing items of type 'TCustom'. myCollection is a collection type that implements 'IEnumerable' but, type 'TCustom' does not implement it.

IEnumerable Iterator()
{ 
  foreach(TCustom item in myCollection)
   {
     yield return item;
   }
}

class RandomCollection : IEnumerable{....}
class TCustom {....}
RandomCollection myCollection = new RandomCollection();

so the yield statement is returning 'item' object of type 'TCustom' from 'myCollection'. If 'TCustom' is a custom type created from my source code, does it have to implement IEnumerable interface? And if type 'TCustom' does not implement 'IEnumerable' interface, can it be a return type of yield return statement? (yield return item;)

  • 1
    `yield return` produced the individual items in the collection, so T does not have to (and usually does not) implement IEnumerable. – Klaus Gütter Sep 26 '21 at 11:04
  • 1
    FYI a single T is usually a placeholder for a Type in generics, not a specific class. It confused me at first – Hans Kesting Sep 26 '21 at 11:12
  • @KlausGütter could you please elaborate on why individual items need not implement IEnumerable? And isn't there any specific operand type for 'yield' ? – Samin Sadman Shad Sep 26 '21 at 11:37
  • 1
    It depends on the type of the collection. If it is `IEnumerable`, you have to supply an `int`. If simply `IEnumerable`, it can be any `object`. – Klaus Gütter Sep 26 '21 at 11:45
  • Does this answer your question? [What is the yield keyword used for in C#?](https://stackoverflow.com/questions/39476/what-is-the-yield-keyword-used-for-in-c) It is completely transformed into a separate class, which implements `IEnumerable` or `IEnumerable` – Charlieface Sep 26 '21 at 12:06
  • @Charlieface actually that thread does not clarify the return type of the yield statement, especially the confusion I encountered – Samin Sadman Shad Sep 26 '21 at 14:58
  • @KlausGütter thank you for clarifying it. Additional question Ithat came to my mind, that the Object class does not implement IEnumerable, so how any object type in 'yield return object' also serves for IEnumerator? – Samin Sadman Shad Sep 26 '21 at 15:01
  • 1
    Again: what you return in yield return is not the collection, it is an individual element. Only all of the encountered yield return's together form the final collection. – Klaus Gütter Sep 26 '21 at 15:08
  • Once you understand how the state machine works, it should be pretty obvious what is being returned: the overall function outputs an `IEnumerable` but each `yield` statement only outputs one value being enumerated – Charlieface Sep 26 '21 at 18:05

1 Answers1

1

IEnumerable is an interface that defines one method GetEnumerator which returns an IEnumerator interface, this in turn allows readonly access to a collection. A collection that implements IEnumerable can be used with a foreach statement.

Definition

IEnumerable 

public IEnumerator GetEnumerator();

IEnumerator

public object Current;
public void Reset();
public bool MoveNext();

example code from codebetter.com

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.

Which do you use? The only reason to use IEnumerator is if you have something that has a nonstandard way of enumerating (that is, of returning its various elements one-by-one), and you need to define how that works. You'd create a new class implementing IEnumerator. But you'd still need to return that IEnumerator in an IEnumerable class.

For a look at what an enumerator (implementing IEnumerator<T>) looks like, see any Enumerator<T> class, such as the ones contained in List<T>, Queue<T>, or Stack<T>. For a look at a class implementing IEnumerable, see any standard collection class.

Dor Lugasi-Gal
  • 1,430
  • 13
  • 35