Tengo el siguiente código
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
El dispose()método se llama al final de las usingllaves de declaración, }¿verdad? Dado que returnantes del final de la usingdeclaración, ¿el MemoryStreamobjeto se eliminará correctamente? ¿Qué pasa aquí?

Respuestas:
Sí,
Disposese llamará. Se llama tan pronto como la ejecución abandona el alcance delusingbloque, independientemente de los medios que tomó para abandonar el bloque, ya sea el final de la ejecución del bloque, unareturndeclaración o una excepción.Como @Noldorin señala correctamente, el uso de un
usingbloque en el código se compila entry/finally, con laDisposellamada en elfinallybloque. Por ejemplo, el siguiente código:efectivamente se convierte en:
Por lo tanto, porque
finallyse garantiza que se ejecutará después de que eltrybloque haya finalizado la ejecución, independientemente de su ruta de ejecución,Disposese garantiza que se llamará, pase lo que pase.Para obtener más información, consulte este artículo de MSDN .
Apéndice:
Solo una pequeña advertencia para agregar: debido a que
Disposese garantiza que se llamará, casi siempre es una buena idea asegurarse de queDisposenunca se produzca una excepción cuando se implementaIDisposable. Por desgracia, hay algunas clases en la biblioteca central que hacen un tiro en ciertas circunstancias cuandoDisposese llama - que estoy mirando a ti, proxy de servicio WCF Referencia / cliente! - y cuando eso sucede, puede ser muy difícil rastrear la excepción original siDisposese llamó durante un desenrollado de la pila de excepciones, ya que la excepción original se traga a favor de la nueva excepción generada por laDisposellamada. Puede resultar tremendamente frustrante. ¿O es eso frustrantemente enloquecedor? Uno de los dos. Tal vez ambos.fuente
Disposefinalmente, por lo que está funcionando efectivamente con la implementación definally, como usted describe.usingLas declaraciones se comportan exactamente comotry ... finallybloques, por lo que siempre se ejecutarán en cualquier ruta de salida de código. Sin embargo, creo que están sujetos a muy pocas y raras situaciones en las quefinallyno se llaman bloques. Un ejemplo que puedo recordar es si el subproceso en primer plano sale mientras los subprocesos en segundo plano están activos: todos los subprocesos, excepto el GC, están en pausa, lo que significa que losfinallybloques no se ejecutan.Edición obvia: se comportan igual aparte de la lógica que les permite manejar objetos IDisposable, d'oh.
Contenido adicional: se pueden apilar (donde los tipos difieren):
Y también delimitado por comas (donde los tipos son los mismos):
fuente
Su objeto MemoryStream se eliminará correctamente, no hay necesidad de preocuparse por eso.
fuente
Con la
usingdeclaración, el objeto se eliminará independientemente de la ruta de finalización.Otras lecturas...
fuente
Eche un vistazo a su código en reflector después de compilarlo. Verá que el compilador refactoriza el código para asegurarse de que se llame a dispose en la secuencia.
fuente