Implementing IEnumerable on an Enumerator?

  • Thread starter Thread starter Gordon Rundle
  • Start date Start date
G

Gordon Rundle

It drives me nuts that I can't use foreach with an enumerator
instance. I would like the following to be functionally identical:
foreach (Object o in MyCollection) ...
foreach (Object o in MyCollection.GetEnumerator()) ...

For enumerable types that are under my control, is there any reason
not to create an enumerator type that itself implements IEnumerable?
Like so:

class MyEnumerator : IEnumerable, IEnumerator {
private IEnumerator mEnumerator = null;
public MyEnumerator(IEnumerator e) { mEnumerator = e; }
public MyEnumerator(IEnumerable e) { mEnumerator =
e.GetEnumerator(); }
public object Current { get { return mEnumerator.Current; } }
public void Reset() { mEnumerator.Reset(); }
public bool MoveNext() { return mEnumerator.MoveNext(); }
public IEnumerator GetEnumerator() { return this; }
}


I understand that using the foreach construct, Dispose() will be
called on the enumerator at the end of the loop, if it's defined; what
are the implications for a wrapper class like this? Are there other
possible issues I should be aware of?

thanks,
G. Rundle
 
Gordon Rundle said:
It drives me nuts that I can't use foreach with an enumerator
instance. I would like the following to be functionally identical:
foreach (Object o in MyCollection) ...
foreach (Object o in MyCollection.GetEnumerator()) ...

The reason is that enumerators are stateful and after the foreach statement
are fully consumed. A type that implements IEnumerable can dispense endless
enumerators.
I understand that using the foreach construct, Dispose() will be
called on the enumerator at the end of the loop, if it's defined; what
are the implications for a wrapper class like this? Are there other
possible issues I should be aware of?

If the enumerator implements IDisposable it will be disposed. If it doesn't,
it won't.
 
The reason is that enumerators are stateful and after the foreach statement
are fully consumed. A type that implements IEnumerable can dispense endless
enumerators.

An example may be clearer:

If you allowed enumerators in foreach, this code would probably not work as
expected:

LoanEnumerator loans = borrower.Loans;
foreach(Loan loan in loans)
PrintLoan(loan);
// loans enumerator instance already consumed at this point
foreach(Loan loan in loans)
RecordLoan(loan);
 
Back
Top