2011-02-13 18 views
48

En C#, ¿Foreach llama automáticamente a Dispose en cualquier objeto que implemente IDisposable?¿Foreach llama automáticamente a Dispose?

http://msdn.microsoft.com/en-us/library/aa664754(v=vs.71).aspx parece indicar que lo hace:

* De lo contrario, la expresión de recogida es de un tipo que implementa System.IEnumerable, y la expansión de la instrucción foreach es: Copiar

IEnumerator enumerator = 
     ((System.Collections.IEnumerable)(collection)).GetEnumerator(); 
try { 
    while (enumerator.MoveNext()) { 
     ElementType element = (ElementType)enumerator.Current; 
     statement; 
    } 
} 
finally { 
    IDisposable disposable = enumerator as System.IDisposable; 
    if (disposable != null) disposable.Dispose(); 
} 

Respuesta

41

Sí, foreach llamará a Dispose() en el enumerador si implementa IDisposable.

+0

¿Se refiere al _enumerable_ o al _enumerator_? – zneak

+1

@zneak: es el enumerador. Un enumerable simplemente proporciona una forma de recuperar un enumerador. –

+0

Gracias Matt! Es tarde donde estoy y no estaba seguro de si estaba leyendo el documento msdn correctamente, necesitaba otra opinión. – jim

10

Esta pregunta/respuesta está mal redactada.

No está claro si la pregunta es:

Q: "¿Tiene foreach desechar objetos devueltos por el empadronador antes de pasar a la siguiente"

A: La respuesta es, por supuesto, NO. No hace más que proporcionar una forma conveniente de ejecutar un código una vez para cada objeto en una enumeración.

O sea que signifique:

Q: "Bajo el capó, foreach utiliza un objeto enumerable ¿Esto puede dispuesta después de la llamada a forEach, incluso si hay una excepción en el bloque iterador?"

A: La respuesta es (aún bastante obvia) ¡SÍ! Como la sintaxis no le proporciona acceso al enumerador, tiene la responsabilidad de eliminarlo.

La respuesta a la segunda pregunta es dónde surge la confusión, ya que las personas han escuchado que foreach se expande a un bloque while con un bloque try/finally. El propósito de esto finalmente es asegurar que el enumerador esté dispuesto si implementa IDisposable.

en caso de tener que verlo por ti mismo: See it in action here

Espero que esto ayude a aclarar! ;)

+0

Por "foreach usa un objeto enumerable", quiso decir "foreach usa un enumerador dado por la colección enumerable". – efdee

Cuestiones relacionadas