These two questions almost answer my own question, but not quite. Consider this a follow-up question to these.
I understand that a foreach loop will Dispose of an enumerator when it's done with it.
My question is this:
If the enumerator in question is actually a c# iterator block (i.e. GetEnumerator()/yield) of an IEnumerable<T> class which itself implements IDisposable, can I be sure that the object itself will be disposed? Or do I need to resort to calling GetEnumerator()/MoveNext()/Current explicitly inside a using block?
EDIT: This snippet demonstrates @JonSkeet's answer.
EDIT #2: This snippet, based on @JonSkeet's comments, demonstrates ideal usage. The iterator block is responsible for the lifetime of needed resources, not the enumerable object itself. This way, the enumerable can be enumerated multiple times if need be -- each enumerable has its own resource to work with.
foreach calls Dispose on the iterator regardless of the implementation of that iterator. It doesn't matter if it was created with an iterator block or not, it's Dispose method is called either way.
That's the whole point of interfaces, such as IDisposable. You don't need to care what the underlying implementation is. It always disposes of everything. What they choose to do with that call is up to them.
As for the IEnumerable<T> (not the IEnumerator<T>) generated by the iterator block, it will never implement IDisposable, and thus cannot be disposed. If you have a custom object (rather than an iterator block) that implements IEnumerable<T> and IDisposable, then it will not be disposed of when used in a foreach. Only the IEnumerator<T> created through GetEnumerator will be.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With