2012-09-03 12 views
8

Si tengo un bloque de uso que rodea una declaración try catch, ¿qué pasará con el objeto dentro de esa declaración de uso si el catch dispara una excepción? Considere el siguiente código:Usando instrucción con try catch. ¿Qué sucede con la instancia de using statement?

using (IDatabaseConnectivityObject databaseConnectivityObject = new DbProviderFactoryConnectionBasicResponse()) 
{ 
    try 
    { 
     Foo(); 
    } 
    catch (ArgumentNullException e) 
    { 
     throw; 
    } 
} 

Si asumimos Foo() falla y la excepción es despedido y efectivamente rompe el programa databaseConnectivityObject ser eliminados? La razón por la que esto es importante es porque el objeto tiene una conexión de base de datos asociada.

Respuesta

9

Puede pensar en using como una mano corta para try-finally. Por lo tanto, su código es equivalente a:

IDatabaseConnectivityObject databaseConnectivityObject = new DbProviderFactoryConnectionBasicResponse(); 
try 
{ 
    try 
    { 
     Foo(); 
    } 
    catch(ArgumentNullException e) 
    { 
     throw; 
    } 
} 
finally 
{ 
    if(databaseConnectivityObject != null)//this test is often optimised away 
    databaseConnectivityObject.Dispose() 
} 

Visto de esta manera, se puede ver que la Dispose() de hecho se llamará si la excepción lanza, porque el try-finally está fuera del try-catch.

Es por eso que utilizamos using.

+0

Gracias Jon. Su ejemplo de código lo deja muy claro. – CSharpened

7

suponemos que Foo() falla y se dispara la excepción y se rompe el programa efectivamente se borrará el programa DatabaseConnectivityObject?

Sí lo será. utilizando utiliza internamente try-finally, (usando sólo funciona para aquellos que implementa IDisposable)

De MSDN- using statement

La instrucción using asegura que Desechar se llama incluso si se produce una excepción mientras estás métodos de llamada en el objeto. Puede obtener el mismo resultado colocando el objeto dentro de un bloque try y llamando al Dispose en un bloque finally; de hecho, así es como el compilador traduce la declaración de uso .

+0

Así que, en efecto, el uso está diciendo prueba todo el código dentro del bloque de uso y finalmente llama a MyObject.Dispose() en el bloque finally que no vemos? – CSharpened

+1

@CSharpened, absolutamente correcto, ese es el caso. Puede ver un ejemplo más detallado en el enlace en la respuesta – Habib

3

Sí, su bloque using dispondrá de la base de datosConnectivityObject, independientemente de si tiene un bloque try - catch.

Dice correctamente que el uso del bloque es importante y debe usarlo para todas las clases que implementan IDisposable para asegurarse de que se eliminen correctamente incluso en el caso de una excepción.

De MSDN- using statement

La instrucción using asegura que Desechar se llama incluso si se produce una excepción mientras que está llamando a métodos en el objeto. Puede obtener el mismo resultado colocando el objeto dentro de un bloque try y llamando al Dispose en un bloque finally; de hecho, así es como el compilador traduce la declaración de uso .

3

Al implementar el bloque using será dispuesto el objeto en los paréntesis, si se implementa la interfaz IDisposable.

Aún se eliminará aunque falle foo().

El objeto dentro de la sentencia using debe implementar la interfaz IDisposable.

Además, estas preguntas "Uses of using in c sharp" y "using statement vs try finally" hablan más sobre los usos y aspectos prácticos de la declaración using.

La sección 8.13 del C# Language Specification detalla claramente la declaración de uso.

2

Su código using es equivalente a

IDatabaseConnectivityObject databaseConnectivityObject = new IDatabaseConnectivityObject(); 
try 
{ 
//To do code here 
} 
finally 
{ 
    if(databaseConnectivityObject!=null) 
    { 
     databaseConnectivityObject.Dispose(); 
    } 
} 

Una instrucción using clasifica principalmente en tres partes, es decir,

  1. Adquisición
  2. Uso
  3. eliminación

En primer lugar, los recursos se adquieren y el uso se realiza en el bloque try con la instrucción finally. Por último, el objeto se elimina finalmente como se indica en el código equivalente anterior ...

+1

Creo que vale la pena señalar que la prueba nula normalmente se optimiza cuando puede, al explicarla. Alguien podría sentirse tentado a hacer su propia prueba, finalmente como una micro-optimización. Eso sería una mala idea de todos modos (la reducción en la legibilidad no valdría la pena), pero el hecho de que ni siquiera ofrecerá el pequeño beneficio que creen que podría, lo desalentará aún más. –