[c#] ¿Es este un uso razonable del operador ternario?


Answers

El operador ternario está destinado a devolver un valor.

IMO, no debe mutar el estado, y se debe usar el valor de retorno.

En el otro caso, use declaraciones if. Si las declaraciones están destinadas a ejecutar bloques de código.

Question

¿Hay algún problema de comprensión / mantenimiento que resulte de código como

inVar1 == 0 ? NULL : v.push_back(inVar1);
inVar2 == 0 ? NULL : v.push_back(inVar2);

Etcétera.

La idea posiblemente confusa es usar el operador ternario para el flujo del programa en lugar de la asignación de variables, que es la explicación habitual.

No he visto normas de codificación en el trabajo que aborden este uso, así que aunque me siento cómodo haciendo esto, me gustaría saber si existe una buena razón para no hacerlo.




Si tiene varias invocaciones de método en uno o ambos argumentos tenarios, entonces es incorrecto. Todas las líneas de código independientemente de qué enunciado deben ser breves y simples, idealmente no compuestas.




Como se mencionó, no es más corto o más claro que una declaración de 1 línea si. Sin embargo, ya no es más, y no es tan difícil de asimilar. Si conoces al operador ternario, es bastante obvio lo que está sucediendo.

Después de todo, no creo que alguien tenga un problema si se le está asignando a una variable (incluso si también estuviera mutando):

var2 = inVar1 == 0 ? NULL : v.push_back(inVar1);

El hecho de que el operador ternario siempre devuelva un valor - IMO - es irrelevante. Ciertamente, no es necesario que use todos los valores devueltos ... después de todo, una asignación devuelve un valor.

Dicho eso, lo reemplazaría con una declaración if si lo encontré con una rama NULL.

Pero , si reemplazó una declaración de 3 líneas if:

if (inVar == 0) {
   v.doThingOne(1);
} else {
   v.doThingTwo(2);
}

con:

invar1 == 0 ? v.doThingOne(1) : v.doThingTwo(2);

Podría dejarlo ... dependiendo de mi estado de ánimo. ;)




Si bien, en la práctica, estoy de acuerdo con los sentimientos de aquellos que desalientan este tipo de escritura (cuando lees, tienes que hacer un trabajo extra para escanear la expresión por sus efectos secundarios), me gustaría ofrecer

!inVar1 ?: v.push_back(inVar1);
!inVar2 ?: v.push_back(inVar2);

... si vas por oscuro, eso es. GCC permite x ?: y en lugar de x ? x : y x ? x : y . :-)




Creo que sería mejor que te desempeñes en una estructura adecuada. Incluso prefiero tener llaves siempre con mis estructuras if, en caso de que tenga que agregar líneas más adelante a la ejecución condicional.

if (inVar != 0) {
    v.push_back(inVar);
}



Su uso del operador ternario no le gana nada y perjudica la legibilidad de los códigos.

Como el operador ternario devuelve un valor que no está utilizando, es un código impar. El uso de un if es mucho más claro en un caso como el tuyo.




La mayoría de los ternarios torturados (¿cómo es eso de la aliteración?) Veo que son simplemente intentos de poner la lógica que realmente pertenece en una declaración if en un lugar donde una sentencia if no pertenece o no puede ir.

Por ejemplo:

if (inVar1 != 0)
  v.push_back(inVar1);
if (inVar2 != 0)
  v.push_back(inVar2);

funciona suponiendo que v.push_back es nulo, pero ¿qué sucede si devuelve un valor que necesita pasar a otra función? En ese caso, debería verse algo como esto:

SomeType st;
if (inVar1 != 0)
  st = v.push_back(inVar1);
else if (inVar2 != 0)
  st = v.push_back(inVar2);
SomeFunc(st);

Pero eso es más para digerir un código tan simple. Mi solución: definir otra función.

SomeType GetST(V v, int inVar1, int inVar2){
    if (inVar1 != 0)
      return v.push_back(inVar1);
    if (inVar2 != 0)
      return v.push_back(inVar2);        
}

//elsewhere
SomeFunc(GetST(V v, inVar1, inVar2));

En cualquier caso, el punto es el siguiente: si tienes una lógica que está demasiado torturada para un ternario pero que desordene tu código si se coloca en una declaración if, ¡ponlo en otro lugar!




Creo que esto debería evitarse. Podría usar una instrucción if de 1 línea en su lugar.

if(inVar1 != 0) v.push_back(inVar1);



Links



Tags

c# c#   c++ c++   c   ternary