¿Cuál de estos es mejor para la mantenibilidad?
if (byteArrayVariable != null)
if (byteArrayVariable .Length != 0)
//Do something with byteArrayVariable
O
if ((byteArrayVariable != null) && (byteArrayVariable.Length != 0))
//Do something with byteArrayVariable
Prefiero leer y escribir el segundo, pero recuerdo leer en código completo que hacer cosas así es malo para la mantenibilidad.
Esto se debe a que confía en el idioma para no evaluar la segunda parte de if
si la primera parte es falsa y no todos los idiomas lo hacen. (La segunda parte arrojará una excepción si se evalúa con un valor nulo byteArrayVariable
).
No sé si eso es realmente algo de qué preocuparse o no, y me gustaría recibir comentarios generales sobre la pregunta.
Gracias.
&&
y los||
operadores que realizan la evaluación de corto circuito. Pasar de un idioma a otro generalmente tiene algunos inconvenientes, y es bueno ser firme al hacer revisiones de código para ayudar a detectar esos pequeños problemas.Respuestas:
Creo que la segunda forma está bien, y también representa más claramente lo que estás tratando de hacer. Tu dices eso...
No importa si todos los idiomas hacen eso. Estás escribiendo en un idioma en particular, por lo que solo importa si ese idioma lo hace. De lo contrario, básicamente está diciendo que no debe usar las funciones de un idioma en particular porque otros idiomas pueden no ser compatibles con esas funciones, y eso es una tontería.
fuente
Me sorprende que nadie lo haya mencionado (así que espero no haber leído mal la pregunta), ¡ pero ambos son una mierda!
La mejor alternativa sería utilizar salidas anticipadas (colocar una declaración de retorno al principio del código si no se ejecuta ningún otro código). Esto supone que su código está relativamente bien refactorizado y que cada método tiene un propósito conciso.
En ese momento harías algo como:
Puede parecerse mucho a la validación, y eso es precisamente lo que es. Valida que se hayan cumplido las condiciones para que el método haga lo suyo: ambas opciones que ofreció ocultaron la lógica real dentro de las comprobaciones previas.
Si su código es una gran cantidad de espagueti (métodos muy largos, muchos ifs anidados con lógica dispersa entre ellos, etc.), entonces debe centrarse en el problema más grande de poner su código en forma antes de los problemas estilísticos más pequeños. Dependiendo de su entorno y la gravedad del desorden, existen algunas herramientas excelentes para ayudar (por ejemplo, Visual Studio tiene una función de refactorización de "Método de extracción").
Como Jim menciona, todavía hay espacio para el debate sobre cómo estructurar la salida anticipada. La alternativa a lo anterior sería:
fuente
No pierda el tiempo tratando de atrapar por cada no esta condición. Si puede descalificar los datos o la condición, hágalo lo antes posible.
Esto le permite adaptar su código mucho más fácilmente para nuevas condiciones
fuente
Su ejemplo es el ejemplo perfecto de por qué los anidados
ifs
son un mal enfoque para la mayoría de los idiomas que admiten correctamente la comparación booleana. Anidarifs
crea una situación en la que su intención no está del todo clara. ¿Se requiere que el segundoif
siga inmediatamente al primero? ¿O es solo porque todavía no has puesto otra operación allí?En este caso, estos deben estar juntos. Actúan como guardia para garantizar que no realice una operación que resulte en una excepción. Usando anidado
ifs
, lo deja a la interpretación de la persona que lo sigue en cuanto a si los dos representan un guardia de dos partes o alguna otra lógica de ramificación. Al combinarlos en un soloif
, estoy afirmando eso. Es mucho más difícil esconder una operación dentro de allí donde no debería estar.Siempre favoreceré una comunicación clara de mi intención sobre la estúpida afirmación de alguien de que "no funciona en todos los idiomas". Adivina qué ...
throw
tampoco funciona en todos los lenguajes, ¿eso significa que no debería usarlo al codificar en C # o Java y en su lugar debería confiar en los valores de retorno para señalar cuando hubo un problema?Dicho todo esto, es mucho más fácil de leer para invertirlo y simplemente volverán de método si bien es no satisfecho como dice STW en su respuesta.
fuente
En este caso, sus dos cláusulas están directamente relacionadas, por lo que es preferible la segunda forma.
Si no estuvieran relacionados (por ejemplo, una serie de cláusulas de protección en diferentes condiciones), preferiría la primera forma (o refactorizaría un método con un nombre que represente lo que realmente representa la condición compuesta).
fuente
Si trabaja en Delphi, la primera forma es, en general, más segura. (Para el ejemplo dado, no hay mucho que ganar usando ifs anidados).
Delphi le permite especificar si las expresiones booleanas evalúan o no "cortocircuito", a través de conmutadores de compilación. Hacer la forma # 1 (ifs anidados) le permite asegurarse de que la segunda cláusula se ejecute si y solo si (y estrictamente después ) la primera cláusula se evalúa como verdadera.
fuente
El segundo estilo puede ser contraproducente en VBA, ya que si la primera prueba es si el objeto generado, todavía hará la segunda prueba y se eliminará el error. Acabo de acostumbrarme a VBA cuando trato con la verificación de objetos para usar siempre el primer método.
fuente
La segunda forma es más legible, especialmente si está utilizando bloques {} alrededor de cada cláusula, porque la primera forma conducirá a bloques anidados {} y múltiples niveles de sangría, lo que puede ser difícil de leer (debe contar los espacios de sangría para averiguar dónde termina cada bloque).
fuente
Los encuentro legibles, y no acepto el argumento de que debería preocuparse por el mantenimiento del código si cambiara de idioma.
En algunos idiomas, la segunda opción funciona mejor, por lo que sería una opción clara.
fuente
Estoy contigo; Lo hago de la segunda manera. Para mí, es lógicamente más claro. La preocupación de que algunos idiomas ejecuten la segunda parte incluso si la primera se evalúa como falsa me parece un poco tonta, ya que nunca en mi vida he escrito un programa que se ejecute en "algunos idiomas"; mi código siempre parece existir en un lenguaje específico, que puede manejar esa construcción o no. (Y si no estoy seguro de si el lenguaje específico puede manejarlo, eso es algo que realmente necesito aprender, ¿no es así?)
En mi opinión, el peligro con la primera forma de hacerlo es que me deja vulnerable a poner accidentalmente un código fuera de ese
if
bloque anidado cuando no era mi intención. Lo cual, sin duda, no es una gran preocupación, pero parece más razonable que preocuparse por si mi código es independiente del lenguaje.fuente
Prefiero la segunda opción, porque es más legible.
Si la lógica que está implementando es más compleja (comprobar que una cadena no es nula y no está vacía es solo un ejemplo), puede realizar una refactorización útil: extraer una función booleana. Estoy con @mipadi en el comentario "Code Complete" ("no importa si todos los idiomas hacen eso ...") Si el lector de su código no está interesado en mirar dentro de la función extraída, entonces el orden en el que se evalúan los operandos booleanos se convierte en una cuestión discutible para ellos.
fuente
pero esa es básicamente la segunda opción.
fuente