No, you don't need to worry about this.
The fact that they return an IDisposable
implementation 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 both IEnumerable<T>
and IEnumerator<T>
. The latter extends IDisposable
, which is why you're seeing it.
Sample code to demonstrate this:
using System;
using System.Collections.Generic;
public class Test
{
static void Main()
{
IEnumerable<int> foo = Foo();
Console.WriteLine(foo is IDisposable); // Prints True
}
static IEnumerable<int> Foo()
{
yield break;
}
}
Note that you do need to take note of the fact that IEnumerator<T>
implements IDisposable
. 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:
using (var enumerator = enumerable.GetEnumerator())
{
if (!enumerator.MoveNext())
{
throw // some kind of exception;
}
var value = enumerator.Current;
while (enumerator.MoveNext())
{
// Do something with value and enumerator.Current
}
}
(A foreach
loop will do this automatically, of course.)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…