Sí, Dispose
se llamará. Se llama tan pronto como la ejecución abandona el alcance del using
bloque, independientemente de los medios que tomó para abandonar el bloque, ya sea el final de la ejecución del bloque, una return
declaración o una excepción.
Como @Noldorin señala correctamente, el uso de un using
bloque en el código se compila en try
/ finally
, con la Dispose
llamada en el finally
bloque. Por ejemplo, el siguiente código:
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
efectivamente se convierte en:
MemoryStream ms = new MemoryStream();
try
{
// code
return 0;
}
finally
{
ms.Dispose();
}
Por lo tanto, porque finally
se garantiza que se ejecutará después de que el try
bloque haya finalizado la ejecución, independientemente de su ruta de ejecución, Dispose
se 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 Dispose
se garantiza que se llamará, casi siempre es una buena idea asegurarse de que Dispose
nunca se produzca una excepción cuando se implementa IDisposable
. Por desgracia, hay algunas clases en la biblioteca central que hacen un tiro en ciertas circunstancias cuando Dispose
se 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 si Dispose
se 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 la Dispose
llamada. Puede resultar tremendamente frustrante. ¿O es eso frustrantemente enloquecedor? Uno de los dos. Tal vez ambos.