Nein, darüber brauchen Sie sich keine Sorgen zu machen.
Die Tatsache, dass sie eine IDisposable
Implementierung zurückgeben, ist ein Implementierungsdetail. Dies liegt daran, dass Iteratorblöcke in der Microsoft-Implementierung des C # -Compilers zufällig einen einzelnen Typ erstellen, der sowohl IEnumerable<T>
als auch implementiert IEnumerator<T>
. Letzteres erstreckt sich IDisposable
, weshalb Sie es sehen.
Beispielcode, um dies zu demonstrieren:
using System;
using System.Collections.Generic;
public class Test
{
static void Main()
{
IEnumerable<int> foo = Foo();
Console.WriteLine(foo is IDisposable);
}
static IEnumerable<int> Foo()
{
yield break;
}
}
Beachten Sie, dass Sie keine Kenntnis von der Tatsache , dass ergreifen müssen IEnumerator<T>
implementiert IDisposable
. Jedes Mal, wenn Sie explizit iterieren, sollten Sie es ordnungsgemäß entsorgen. Wenn Sie beispielsweise über etwas iterieren und sicherstellen möchten, dass Sie immer einen Wert haben, können Sie Folgendes verwenden:
using (var enumerator = enumerable.GetEnumerator())
{
if (!enumerator.MoveNext())
{
throw
}
var value = enumerator.Current;
while (enumerator.MoveNext())
{
}
}
(Eine foreach
Schleife erledigt dies natürlich automatisch.)
Dispose
eines Interators, derGetEnumerator()
mindestens einmal aufgerufen hat , den vom ersten Aufruf zurückgegebenen Enumerator ungültig macht, jedoch keine von nachfolgenden Aufrufen zurückgegebenen Enumeratoren. Ein AnrufDispose
vor dem erstenGetEnumerator()
Anruf hat keine Auswirkung.supercat
?GetEnumerator()
der eine Referenz auf dieselbe Referenz zurückgibt; Danach werden separate Kopien erstellt. Die Idee ist, nur ein einziges Objekt zu erstellen, wenn häufig nur einmal iteriert wird.