Wenn ich mit Dateien in C # arbeite, bin ich darauf vorbereitet, über die Freigabe der zugehörigen Ressourcen nachzudenken. Normalerweise ist dies eine Verwendungsaussage, es sei denn, es handelt sich um eine Einliner-Komfortmethode wie File.ReadAllLines, das öffnet und schließt die Datei für mich.
.Net 4.0 hat die Komfortmethode File.ReadLines eingeführt. Dadurch wird ein IEnumerable zurückgegeben und es wird eine effizientere Methode zum Verarbeiten einer Datei berechnet - es wird vermieden, die gesamte Datei im Arbeitsspeicher zu speichern. Dazu nehme ich an, dass es im Enumerator eine verzögerte Ausführungslogik gibt.
Offensichtlich, da diese Methode ein IEnumerable zurückgibt, nicht und IDisposable, kann ich nicht mit meiner Bauchreaktion einer using-Anweisung gehen.
Meine Fragen sind: Gibt es zu diesem Zweck irgendwelche Probleme bei der Freigabe von Ressourcen mit dieser Methode?
Bedeutet der Aufruf dieser Methode, dass die Freigabe der zugehörigen Dateisperren nicht deterministisch ist?
IEnumerable
erbt nicht von IDisposable, weil die Klasse, die es implementiert, normalerweise nur die Zusage gibt, aufzählbar zu sein, es hat bisher noch nichts getan, was eine Beseitigung rechtfertigt.
Wenn Sie jedoch darüber aufzählen, rufen Sie zuerst IEnumerator
ab, indem Sie die Methode IEnumerable.GetEnumerator
aufrufen. In der Regel implementiert das zugrunde liegende Objekt IDisposable
.
Die Art und Weise, wie foreach
implementiert wird, ist ähnlich der folgenden:
Wenn das Objekt tatsächlich IDisposable
implementiert, wird es auf diese Weise entsorgt. Für File.ReadLines
wird die Datei erst geöffnet, wenn Sie mit dem Aufzählen beginnen, also muss das Objekt, das Sie von File.ReadLines
erhalten, nicht entsorgt werden, aber der Enumerator, den Sie erhalten, tut dies.
Wie die Kommentare zeigen, erbt IEnumerator
nicht von IDisposable
, obwohl dies bei vielen typischen Implementierungen der Fall ist, während das generische IEnumerator<T>
IDisposable
erbt.
+1 für Lasses Antwort.
Insbesondere für File.ReadLines
, wenn der Enumerator .MoveNext()
aufruft, wird die interne TextReader
entsorgt, wenn ein EOF auftritt oder wenn ein Fehler auftritt.