2009-08-03 6 views
8

¿Cuál es la mejor práctica: devolver un valor de un método dentro de una declaración using o declarar una variable antes, configurarla dentro y devolverla después?Práctica recomendada para volver del uso de bloques

public int Foo() 
{ 
    using(..) 
    { 
    return bar; 
    } 
} 

o

public int Foo() 
{ 
    var b = null; 
    using(..) 
    { 
    b = bar; 
    } 
    return b; 
} 

Respuesta

9

Prefiero el primer ejemplo. Menos variables, menos líneas de código, más fácil de seguir, más fácil de mantener ...

public int Foo() 
{ 
    using(..) 
    { 
    return bar; 
    } 
} 
2

hay razón para no desde que using declaración se traduce en un bloque try...finally y la parte finally está garantizada para ser ejecutado (incluso a través de una devolución o una excepción no controlada).

+1

Alguien siempre tiene que señalar esto - el bloque finally es * no * "garantizado" para ser ejecutado en absoluto. Hay circunstancias bien definidas bajo las cuales se ejecutará, y otras donde no se ejecutará. –

+1

¿Tiene algunos ejemplos donde no? –

+1

@Earwicker: si los casos en los que no se ejecutará ascienden a <0.01%, entonces creo que para la mayoría de los propósitos, podemos decir que está "garantizado". –

1

Todo se reduce a la preferencia personal. Encontrarás argumentos en ambos lados de esta cerca en particular. Yo, estoy a favor de la opción 1: regresar tan pronto como puedas. Creo que expresa mejor la intención del código; no hay razón para quedarse más tiempo de lo necesario. Si has completado todo tu trabajo, regresa.

A veces, tendrá múltiples puntos de retorno posibles, y trabajo de "fin de método" (registro, limpieza) que podría llevarlo a una declaración de devolución única. Nada terrible acerca de eso, pero a menudo puede manejar esas situaciones en bloques finally o con aspectos en la programación orientada a aspectos.

+1

Acepto las preferencias personales. Prefiero hacer regresar al final/final del método. Las pautas de codificación a menudo dictan esto también. Esto probablemente también proviene del hecho de que los métodos a veces son demasiado largos, lo que da como resultado métodos ilegibles. Manténlos realmente cortos y tus métodos son legibles de nuevo. Así que esta es una de esas respuestas "depende", supongo! ;) Mirándolos desde las mejores prácticas, afaik realmente no es uno, es más una cuestión de preferencia. –

5

Siguiendo el principio de "menos es más" (realmente solo una variante de KISS), el primero. Hay menos líneas de código que mantener, ningún cambio en la semántica y ninguna pérdida de legibilidad (podría decirse que este estilo es más fácil de leer).

5

De using Statement - MSDN

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

Desde el try-finally (C# Reference)

finalmente se utiliza para garantizar un bloque declaración de código se ejecuta independientemente de cómo se sale del bloque try anterior.

Para responder a su pregunta, sí, está bien que regrese de una declaración de uso.

+0

Preguntó cuál de las anteriores es una mejor práctica, no para la semántica de la declaración using. Podría decirse que la semántica es relevante aquí, pero no responde la pregunta planteada. – jason

+0

@Jason: es suficiente ... el título de la pregunta es "¿Está bien regresar de un método dentro de una declaración de uso?" ... puedes ver que no soy el único que lee la pregunta de esta manera. –

+1

@Stan R: Veo el potencial de confusión, pero la publicación claramente pregunta sobre las mejores prácticas, no si el bloque finally se ejecutará o no (es decir, la semántica). – jason

3

El segundo es claramente mejor, y puede verificar que funciona bien escribiendo un programa de prueba.

La declaración using en sí no puede tener un valor, que es una limitación.Suponga que tiene un método llamado Open que devuelve un FileStream abierta, y que desea obtener la longitud del archivo:

Console.WriteLine(Open().Length); 

El error no es que no se está disponiendo el FileStream. Así que hay que escribir (similar a su ejemplo):

long length; 

using (FileStream file = Open()) 
    length = file.Length; 

Console.WriteLine(length); 

Pero con un simple extension method, puede escribir esto en su lugar:

Console.WriteLine(Open().Use(file => file.Length)); 

agradable y limpio, y el FileStream consigue desechados de manera adecuada.

+0

Limpio, pero ilegible al mismo tiempo :-) –

+0

heh esto es bastante limpio. gracias por una idea inteligente. –

+0

@Scott P: ¿es esencialmente la misma idea que el '? : 'operador (una" expresión "equivalente a' si'). Algunos encuentran '? : 'menos legible que el enunciado' if' equivalente, creo que a veces puede ser más claro. La eliminación de nombres de variables a menudo ayuda con la claridad. –

1

me siento segundo mejor

public int Foo() 
{ 
    using(..) 
    { 
    return bar; 
    } 
} 

Una cosa que surge en la mente durante el uso de esta forma es que nos vamos a volver entre el uso de lo que será el objeto (que hemos envuelto en el uso) obtendrá dispuestos , la respuesta es sí porque una instrucción using es solo la mezcla del bloque try/finally, está bien regresar de un bloque try también. La expresión de retorno será evaluada, luego se ejecutará el bloque finally, y el método será return then.So go Ahead :)

Cuestiones relacionadas