It’s recently been pointed out to me that various Linq extension methods (such as Where, Select, etc) return an IEnumerable<T> that also happens to be IDisposable. The following evaluates to True
new int[2] {0,1}.Select(x => x*2) is IDisposable
Do I need to dispose of the results of a Where expression?
Whenever I call a method returning IEnumerable<T>, am I (potentially) accepting responsibility for calling dispose when I’ve finished with it?
No, you don’t need to worry about this.
The fact that they return an
IDisposableimplementation is an implementation detail – it’s because iterator blocks in the Microsoft implementation of the C# compiler happen to create a single type which implements bothIEnumerable<T>andIEnumerator<T>. The latter extendsIDisposable, which is why you’re seeing it.Sample code to demonstrate this:
Note that you do need to take note of the fact that
IEnumerator<T>implementsIDisposable. So any time you iterate explicitly, you should dispose of it properly. For example, if you want to iterate over something and be sure that you’ll always have a value, you might use something like:(A
foreachloop will do this automatically, of course.)