Declarar variables de retorno en métodos de C # versus devolver el valor directamente

17

En un debate sobre las variables de retorno, algunos miembros del equipo prefieren un método para devolver el resultado directamente a la persona que llama, mientras que otros prefieren declarar una variable de retorno que luego se devuelve a la persona que llama (ver ejemplos de código a continuación)

El argumento a favor de este último es que permite que un desarrollador que está depurando el código encuentre el valor de retorno del método antes de que vuelva a la persona que llama, lo que hace que el código sea más fácil de entender: esto es especialmente cierto cuando las llamadas a métodos están conectadas en cadena.

¿Hay alguna guía sobre cuál es la más eficiente y / o hay alguna otra razón por la que deberíamos adoptar un estilo sobre otro?

Gracias

    private bool Is2(int a)
    {
        return a == 2;
    }

    private bool Is3(int a)
    {
        var result = a == 3;
        return result;
    }
pb01
fuente
11
Ambos ejemplos se compilarán a la IL idéntica. El único motivo por el que desea el segundo ejemplo es para fines de depuración o si necesita usarlo resultantes de devolverlo.
ChrisF
1
Otra razón sería porque necesita hacer algo más entre calcular el resultado y devolverlo.
tdammers
1
@ChrisF, en realidad no compilan el mismo IL para mí (hay más stloc.0y ldloc.0en la segunda versión). Pero creo que eso sucede solo en modo de depuración. Y no es realmente importante aquí de todos modos.
svick
@svick - OK - Debería haber agregado "en modo de lanzamiento";)
ChrisF
1
Como puedes y a veces deberías (en aras de la brevedad) escribir algo que se parezca: a = b = c;y a == b == cevitaría escribir algo que se parezca a = b == csi puedes. Cuando vi por primera vez una línea de código como esa, me tomó unos segundos descubrir qué está pasando. Ese código se destacó. Me gustaría poner un paréntesis a == 3, pero StyleCop no le gusta, una buena razón para usar la versión número uno. Algo más: esto es esencialmente una lambda, como a => (a == 3). ¿Por qué agregar una línea de código a una función trivial ya hinchada?
Trabajo

Respuestas:

7

Debido a que uso Resharper con Visual Studio, Ctrl-RV (o Ctrl-Alt-V, si usa las combinaciones de teclas Resharper / IntelliJ) convierte su primer ejemplo en su segundo ejemplo. Entonces, cuando quiero depurar, puedo hacerlo fácilmente. Y si olvido volver a ponerlo, no me sentiré mal porque Ctrl-RI lo volverá a poner de nuevo para que sea más fácil de leer.

En serio, pierda su tiempo discutiendo sobre cosas más importantes. Como dónde colocar tus llaves o espacios principales frente a las pestañas.

pdr
fuente
55
Prefiero que mis debates sean sobre personajes invisibles ...
ChaosPandion
Gran consejo, muchachos! Ahora podemos re-factorizar continuamente el código de los demás mucho más rápido de lo que podíamos antes. ¡Probablemente ahorrará más tiempo que discutirlo realmente! :)
pb01
@pdr ¿ctrl + RV funciona solo con resharper? o es algún tipo de combinación de teclas personalizada? no funciona para mi
Jane Doe
@JaneDoe: Me sorprende ver que es una refactorización de Resharper y que VS no tiene un equivalente. Respuesta corregida. Lo siento por eso.
pdr
@ChaosPandion U + 200B por la victoria!
Jesse C. Slicer
18

Personalmente, encuentro el primer ejemplo más fácil de leer. Todavía puede depurarlo, estableciendo un punto de interrupción en la declaración de devolución y agregando a == 2a la ventana de vigilancia o usando la vigilancia rápida.

Pero esto es realmente una cuestión de preferencia personal. Ambas versiones están bien.

Olivier Jacot-Descombes
fuente
8
1 enderezar más difícil de leer código para hacer más fácil la colocación de puntos de ruptura está haciendo cosas en mi humilde opinión la ronda de manera equivocada
jk.
La ventana de observación o la ventana intermedia no siempre son soluciones para este problema, ya que a veces la expresión requiere que se ejecute el subproceso.
JustAnotherUserYouMayKnowOrNot
@JustAnotherUserYouMayKnowOrNot: Sí. También existe la posibilidad de imprimir un mensaje en la ventana de depuración desde un punto de interrupción. Haga clic derecho en el punto de interrupción y seleccione "Cuando se golpea ...".
Olivier Jacot-Descombes
Además, la expresión podría tener efectos secundarios, ejecutarla nuevamente podría ocasionar problemas. Mejor seguir con el resultado var.
JustAnotherUserYouMayKnowOrNot
9

Cuando el código es tan fácil de leer como su ejemplo, no hay nada de malo en devolver el resultado de una operación lógica como return a == 2. Sin embargo, si el valor de retorno es una declaración más compleja o se parece a

return a > 2? doOptionA().getResult() > makeDecision("greaterThan2") : doOptionB().getResult() == makeDecision("lessThan2");

entonces querrá usar variables para almacenar piezas de eso primero y simplificar la declaración de devolución, en aras de la legibilidad.

CFL_Jeff
fuente
2

En un ejemplo simple como ese, cualquiera está bien.

Para ejemplos más complicados, prefiero la segunda forma. Eso es solo porque es más legible y es probable que otros tengan que mantener el código.

Alan Delimon
fuente
Solo si hay un mejor nombre de variable que result, que en sí mismo es un identificador completamente no descriptivo e inútil.
Alexander - Restablece a Mónica el