2010-04-25 10 views
15

Supongamos que tengo el siguiente código:¿Realiza una declaración de uso de C# try/finally?

private void UpdateDB(QuoteDataSet dataSet, Strint tableName) 
{ 
    using(SQLiteConnection conn = new SQLiteConnection(_connectionString)) 
    { 
     conn.Open(); 
     using (SQLiteTransaction transaction = conn.BeginTransaction()) 
     { 
      using (SQLiteCommand cmd = new SQLiteCommand("SELECT * FROM " + tableName, conn)) 
      { 
       using (SQLiteDataAdapter sqliteAdapter = new SQLiteDataAdapter()) 
       { 
        sqliteAdapter.Update(dataSet, tableName); 
       } 
      } 
      transaction.Commit(); 
     } 
    } 
} 

El C# documentación indica que con una declaración using el objeto dentro del ámbito estará dispuesto y he visto varios lugares en los que se sugiere que no es necesario para usar la cláusula try/finally.

lo general rodean mis conexiones con un try/finally, y siempre cerrar la conexión en la cláusula finally. Dado el código anterior, ¿es razonable suponer que la conexión se cerrará si hay una excepción?

+0

similares a http://stackoverflow.com/questions/278902/ usando-comunicado-vs-try-finally –

+5

no es una respuesta a su pregunta. Por favor leer acerca de los ataques de inyección SQL. –

Respuesta

18

You are correct; the using statement compiles to a try/finally block.

El compilador transforma using(resource) statement; en el siguiente código:.

{ 
    ResourceType resource = expression; 
    try { 
     statement; 
    } 
    finally { 
     if (resource != null) ((IDisposable)resource).Dispose(); 
    } 
} 

(El reparto de IDisposable es en caso de ResourceType implementos IDisposable explícitamente

+0

¿Qué es lo mejor para liberar un recurso que no se puede crear una instancia dentro de la instrucción using o que se puede reutilizar o pasar como parámetro? – bjan

+0

@bjan: Depende de la situación. – SLaks

1

se puede asumir que se cerrará la conexión si se obtiene una excepción.

10

Sí, ya sea que necesite usar un fin o una sentencia try/uso. No necesitas ambos.

A using statement es casi lo mismo que una prueba/finalmente, excepto que en C# 3 no se puede reasignar a la variable dentro del bloque de uso.

using (IDisposable d = foo()) 
{ 
    d = null; // Error: Cannot assign to 'd' because it is a 'using variable' 
} 

Anteriormente se podría reasignar pero el objeto original todavía estaría dispuesto, no el objeto recién asignado y también se obtendría esta advertencia de compilación:

asignación Posiblemente incorrecto local 'd', que es el argumento a una declaración de uso o bloqueo. La llamada o desbloqueo de Deshacer ocurrirá en el valor original del local.

+0

lo que es mejor para liberar un recurso que no se pueden crear instancias dentro de instrucción using o ser reutilizado o se pasa como a cabo parámetro? – bjan

6

Sí, la declaración using es básicamente una abreviatura de un bloque try ... finally.

Por ejemplo, este código ...

using (MyDisposableType foo = new MyDisposableType()) 
{ 
    foo.DoSomething(); 
} 

... que equivaldría a la siguiente ...

{ 
    MyDisposableType foo = new MyDisposableType(); 
    try 
    { 
     foo.DoSomething(); 
    } 
    finally 
    { 
     if (foo != null) 
      ((IDisposable)foo).Dispose(); 
    } 
} 
1

Mediante() asegura que el elemento de instancia dentro de los parámetros será eliminados independientemente de lo que ocurra dentro del bloque de código asociado. Esto incluye cerrar la conexión de la base de datos suponiendo que SQLiteConnection maneja su eliminación correctamente.

Cuestiones relacionadas