2010-10-03 22 views
6

Si utilizo la construcción "using", sé que el objeto se elimina automáticamente. ¿Qué sucede si una declaración dentro de un constructo "using" genera una excepción? ¿El objeto "usar" todavía está dispuesto? ¿Si es así cuando?básico sobre "usar" construcción

Respuesta

11

Un bloque using es convertido - por el compilador - a esto:

DisposableType yourObj = new DisposableType(); 
try 
{ 
    //contents of using block 
} 
finally 
{ 
    ((IDisposable)yourObj).Dispose(); 
} 

Al poner la llamada Dispose() en el bloque finally, asegura Dispose es siempre llamada - a menos que, por supuesto, la excepción se produce en el sitio de creación de instancias, ya que eso ocurre fuera del try.

Es importante recordar que using no es un tipo especial de operador o constructo, es algo que el compilador reemplaza con algo más obtuso.

+0

También es importante señalar que, como su ejemplo ilustra, si la llamada a DisposableType() lanza una excepción, no será llamado a Dispose(); los recursos asignados allí antes de la excepción no se liberarán. – Ben

+0

@Ben muy cierto. Lo señalaré explícitamente. –

+0

También hay una prueba 'null' en el bloque' finally'. – Ani

2

This article explains it nicely.

Internamente, este chico malo genera un/finalmente alrededor del objeto tratar de ser asignado y pide a Dispose() para usted. Le ahorra la molestia de crear manualmente el bloque try/finally y llamar a Dispose().

2

Actualmente el uso del bloque es Equivalente para probar - finalmente bloquear, lo que garantiza que finalmente siempre se ejecutará, p.

using (SqlConnection con = new SqlConnection(ConnectionString)) 
{ 
    using (SqlCommand cmd = new SqlCommand("Command", con)) 
    { 
     con.Open(); 
     cmd.ExecuteNonQuery(); 
    } 
} 

igual a

SqlConnection con = null; 
SqlCommand cmd = null; 

try 
{ 
    con = new SqlConnection(ConnectionString); 
    cmd = new SqlCommand("Command", con); 
    con.Open(); 
    cmd.ExecuteNonQuery(); 
} 
finally 
{ 
    if (null != cmd); 
     cmd.Dispose(); 
    if (null != con) 
     con.Dispose(); 
}