Fondamentalement, c'était un oubli. En C# 1.0, foreach
jamais appelé Dispose
. Avec C# 1.2 (introduit dans VS2003 - il n'y a pas de 1.1, bizarrement) foreach
a commencé à vérifier dans le bloc finally
si l'itérateur a implémenté IDisposable
- ils ont dû le faire de cette façon, parce qu'étendre rétrospectivement IEnumerator
étendre IDisposable
aurait brisé l'implémentation de tous IEnumerator
. S'ils avaient conclu qu'il est utile pour foreach
de disposer des itérateurs en premier lieu, je suis sûr que IEnumerator
aurait prolongé IDisposable
. Lorsque C# 2.0 et .NET 2.0 sont sortis, cependant, ils ont eu une nouvelle opportunité - nouvelle interface, nouvel héritage. Il est beaucoup plus logique d'avoir l'interface IDisposable
afin que vous n'ayez pas besoin d'une vérification de l'exécution dans le bloc finally, et maintenant le compilateur sait que si l'itérateur est un IEnumerator<T>
, il peut émettre un appel inconditionnel vers Dispose
.
EDIT: Il est incroyablement utile que Dispose
soit appelée à la fin de l'itération (mais elle se termine).Cela signifie que l'itérateur peut conserver les ressources, ce qui lui permet, disons, de lire un fichier ligne par ligne. Iterator bloque les implémentations Dispose
du générateur qui s'assurent que tous les blocs finally
pertinents au "point d'exécution actuel" de l'itérateur sont exécutés quand ils sont éliminés - afin que vous puissiez écrire du code normal dans l'itérateur et que le nettoyage se fasse correctement.
Rétrospectivement à la spécification 1.0, il a déjà été spécifié. Je n'ai pas encore été en mesure de vérifier cette déclaration antérieure que l'implémentation 1.0 n'a pas appelé Dispose
.
dois-je m'attendre à ce que 'IEnumerable.GetEnumerator' (non générique) soit également' IDisposable'? – Shimmy
@Shimmy: Le code qui accepte des implémentations arbitraires de 'IEnumerable 'non générique est obligé de s'assurer que tout objet jetable retourné par' GetEnumerator' sera éliminé. Code qui ne doit pas être considéré comme brisé. – supercat
@supercact: Depuis que j'ai écrit cette réponse, j'ai trouvé que c'était déjà dans la spécification 1.0. Je n'ai pas réussi à obtenir une installation 1.0 pour vérifier si j'avais raison ou non sur le comportement. Éditera. –