Im Grunde war es ein Versehen. In C # 1.0, foreach
nie genannt Dispose
1 . Mit C # 1.2 (eingeführt in VS2003 - es gibt keine 1.1, bizarrerweise) foreach
begann im finally
Block zu prüfen , ob der Iterator implementiert war oder nicht IDisposable
- sie mussten dies auf diese Weise tun, da eine nachträgliche IEnumerator
Erweiterung IDisposable
die Implementierung aller gebrochen hätte IEnumerator
. Wenn sie herausgefunden hätten, dass es nützlich ist foreach
, Iteratoren überhaupt zu entsorgen, hätte ich mich sicher IEnumerator
erweitert IDisposable
.
Als C # 2.0 und .NET 2.0 herauskamen, hatten sie jedoch eine neue Gelegenheit - neue Schnittstelle, neue Vererbung. Es ist viel sinnvoller, die Schnittstelle IDisposable
so zu erweitern , dass Sie keine Ausführungszeitprüfung im finally-Block benötigen, und jetzt weiß der Compiler, dass der Iterator, wenn er ein Iterator ist, IEnumerator<T>
einen bedingungslosen Aufruf an senden kann Dispose
.
BEARBEITEN: Es ist unglaublich nützlich Dispose
, am Ende der Iteration aufgerufen zu werden (wie auch immer es endet). Dies bedeutet, dass der Iterator an Ressourcen festhalten kann - was es ihm ermöglicht, beispielsweise eine Datei Zeile für Zeile zu lesen. Iteratorblöcke generieren Dispose
Implementierungen, die sicherstellen, dass alle finally
Blöcke, die für den "aktuellen Ausführungspunkt" des Iterators relevant sind, ausgeführt werden, wenn er entsorgt wird. Sie können also normalen Code in den Iterator schreiben und die Bereinigung sollte angemessen erfolgen.
1 Rückblickend auf die 1.0-Spezifikation wurde sie bereits spezifiziert. Ich konnte diese frühere Aussage, dass die 1.0-Implementierung nicht aufgerufen wurde, noch nicht überprüfen Dispose
.
IEnumerable.GetEnumerator
(nicht generischer) vorhanden istIDisposable
?