2012-04-30 28 views
7

me encontré con este código en el sitio de MSDN aquí http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.open.aspx:SqlConnection en C# - práctica de programación segura

private static void OpenSqlConnection(string connectionString) 
{ 
    using (SqlConnection connection = new SqlConnection(connectionString)) 
    { 
     connection.Open(); 
     Console.WriteLine("ServerVersion: {0}", connection.ServerVersion); 
     Console.WriteLine("State: {0}", connection.State); 
    } 
} 

mi pregunta es ... el sitio también señala que .Open() puede lanzar InvalidOperationExceptions y SQLExceptions, pero este ejemplo doesn Parece que los maneja.

¿Esto es solo porque fueron breves con el código, o hay alguna razón por la cual no valen la pena manejarlo aquí? ¿Es posible que los maneje la construcción de alguna manera?

+0

'.Open()' arrojará una excepción si connectionString no es válido, el objeto 'SqlConnection' es nulo o está vacío o si no se pudo establecer conexión con el servidor (o la base de datos local). En ese caso, suponen que la cadena de conexión es válida y la sentencia using asegura que la conexión no es nula. – DangerMonkey

Respuesta

9

¿Es esto solo porque fueron breves con el código, o hay una razón por la que no valen la pena manejarlo aquí? ¿Es posible que lo hagan por utilizando la construcción de alguna manera?

El using palabra clave es el azúcar sintáctica para try/finally ya pesar de posibles excepciones no serán tratados en el código al que hizo referencia, la conexión de SQL se pueden disponer adecuadamente. Probablemente no manejen las posibles excepciones explícitamente porque muchos prefieren dejar que la excepción salte a la capa más alta y manejen la excepción allí.

+0

Gracias a todos, eso aclara mucho. Vengo de un fondo de C++, así que me gustaría verificar dos veces estas cosas para asegurarme de que no están haciendo más de lo que creo que son :) –

3

Depende de si hay algo que pueda "hacer" al atrapar estas excepciones.

Si no, generalmente se considera la mejor práctica para permitir que las excepciones salten en la pila, hasta que lleguen a un punto en el que puedan manejarse de manera significativa (que puede ser un error 500, en el caso de una red -app)

4

Los ejemplos de MSDN se escriben para proporcionar un ejemplo fácil de leer, no para enseñar las mejores prácticas. Esa es una razón por la cual las personas no deberían copiar/pegar código sin entenderlo.

por MSDN

La instrucción using llama al método Dispose en el objeto en la forma correcta , y (cuando se utiliza como se ha mostrado anteriormente) sino que también hace que el objeto sí para ir fuera de alcance tan pronto como se llame a Dispose.

Cerrará la conexión abierta (mediante el uso de finally). No detectará la excepción lanzada. Lo hace envolviendo la declaración adjunta en un try/finally. No hay trampa.

+0

De acuerdo. Parte del problema con las mejores prácticas en el código de ejemplo es que es mucho más difícil para los novatos descubrir qué está pasando. – NotMe

2

Se están manejando estos casos.

La declaración using se traduce en un patrón de disposición adecuado que también maneja la eliminación en casos de excepciones.

En este caso, incluso si se lanza una excepción, la conexión será eliminada.

La excepción en sí saltará.

Consulte using Statement en MSDN para obtener más detalles.

+0

¿Puedes explicarme esto un poco más o dar un enlace que pueda leer? –

+1

No se * manipulan *. –

+1

@KendallFrey - Los casos para su eliminación se manejarán independientemente de las excepciones. Respuesta reformulada – Oded

0

La sentencia using asegura que se llama a Dispose incluso si se produce una excepción mientras se están llamando métodos al objeto. Try/catch es costoso.try/catch puede afectar la optimización del compilador y lo que el programador usaría try/catch over haciendo algo tan simple como comprobar null. Es solo una mala práctica. Capturar una excepción siempre será más lento que hacer una simple comprobación. No estoy diciendo que los use, pero no los use en lugar de programación defensiva.

También, mirar el código del comando "open" sería llamado sólo si hay una válida connection..so sin preocupaciones ....

"Uso" es igual que poner el objeto en el interior de un intento bloquear y luego llamar a Dispose en un bloque finally.

Si aún necesita para manejar las excepciones específicas, incluye el try..catch ..

+0

-1: 'using' no hace nada para evitar que la aplicación rompiendo –

+0

Gracias John por aclararlo ... – Charls

0

Esta muestra es confuso, aunque técnicamente correcta. En una aplicación del mundo real, esta muestra "tal cual" no tiene ningún valor.
Ni siquiera devuelven el SqlConnection a un código de llamada.
Entonces "estaban siendo breves con el código" como dijiste.

En un escenario del mundo real que podría tener un método como este

private static SqlConnection OpenSqlConnection(string connectionString) 
{ 
    SqlConnection connection = new SqlConnection(connectionString) 
    connection.Open(); 
    return connection;  
} 

y luego utilizarlo en su código (aunque no hay mucho que ganar)

using(SqlConnection cnn = OpenSqlConnection(connectionString)) 
{ 
    // Do your work here 
    .... 
} 

por supuesto, el uso de La declaración oculta todos los trabajos para detectar excepciones y cerrar/eliminar todo, mientras que, técnicamente hablando, se manejan las excepciones, en realidad no se obtienen pistas si algo falla.

+0

¿Qué quiere decir con "no obtiene ninguna pista"? Obtienes una excepción, que es una "pista" muy grande. –

+0

@JohnSaunders Estaba pensando en esto. Si 'using' es como un bloque try/finally, ¿qué ocurre si dentro del bloque de uso obtenemos una excepción?¿Estará burbujeando afuera del bloque y podemos tomar nota o será 'comido' por el finalmente enmascarado por el corsé de cierre? – Steve

+0

Acabo de encontrar [esto] (http://stackoverflow.com/questions/911626/catch-exceptions-within-a-using-block-vs-outside-the-using-block-which-is-bett), leyendo ahora para entender mejor – Steve

1
using (SqlConnection connection = new SqlConnection(connectionString)) 
    { 

    } 

es equivalente a

try 
{ 

    SqlConnection connection = new SqlConnection(connectionString) 
} 
finally 
{ 
    connection.Dispose(); 
} 

"usando" es sólo para asegurarse de que el método dispose() en el objeto se llama (en este caso para asegurarse de que la conexión se volvió a la conexión piscina). "usar" nunca fue para reemplazar la captura.

En los proyectos en los que he trabajado, generalmente tenemos muchas posibilidades de probarlo finalmente. Catch se usa solo en el nivel más alto para iniciar sesión. Una de las razones por las que no se debe utilizar la captura para volver a generar errores (en lugar de registrarla) es que la captura consume muchos recursos.