Básicamente fue un descuido. En C# 1.0, foreach
nunca llamado Dispose
. Con C# 1.2 (introducido en VS2003 - no hay 1.1, extrañamente) foreach
comenzó a verificar en el bloque finally
si el iterador implementó IDisposable
- tenían que hacerlo de esa manera, porque retrospectivamente hacer IEnumerator
ampliar IDisposable
habría roto la implementación de todos IEnumerator
. Si hubieran descubierto que es útil para el foreach
deshacerse de los iteradores en primer lugar, estoy seguro de que IEnumerator
habría extendido IDisposable
.
Cuando aparecieron C# 2.0 y .NET 2.0, sin embargo, tuvieron una nueva oportunidad: nueva interfaz, nueva herencia. Tiene mucho más sentido que la interfaz extienda IDisposable
para que no necesite una verificación en tiempo de ejecución en el bloque finally, y ahora el compilador sabe que si el iterador es IEnumerator<T>
puede emitir una llamada incondicional al Dispose
.
EDITAR: Es increíblemente útil llamar al Dispose
al final de la iteración (como sea que termine).Significa que el iterador puede conservar los recursos, lo que hace que sea factible, por ejemplo, leer un archivo línea por línea. El iterador bloquea las implementaciones del generador Dispose
que aseguran que cualquier bloque finally
relevante para el "punto de ejecución actual" del iterador se ejecute cuando se elimine, de modo que pueda escribir código normal dentro del iterador y la limpieza se realice de forma adecuada.
Mirando hacia atrás en la especificación 1.0, que ya se ha especificado. Todavía no he podido verificar esta afirmación anterior de que la implementación 1.0 no llamó al Dispose
.
¿tengo que esperar que un 'IEnumerable.GetEnumerator' (no genérico) sea' IDisposable' también? – Shimmy
@Shimmy: El código que acepta implementaciones arbitrarias de 'IEnumerable' no genérico está obligado a garantizar que cualquier objeto desechable devuelto por' GetEnumerator' será eliminado. Código que no debe considerarse roto. – supercat
@supercat: Desde que escribí esta respuesta, descubrí que ya estaba en la especificación 1.0. No he logrado obtener una instalación de 1.0 para verificar si tenía razón o no sobre el comportamiento. Editaré –