Pregunta

Ahh, no te gusta una buena abuso ternaria? :) Considere la siguiente expresión:

true ? true : true ? false : false

Para aquellos de ustedes que ahora son completamente perplejos, que se puede decir que esto se evalúa como true . En otras palabras, es equivalente a esto:

true ? true : (true ? false : false)

Pero, ¿es fiable? ¿Puedo estar seguro de que, bajo ciertas circunstancias, no vendrá a esto:

(true ? true : true) ? false : false

Algunos podrían decir - bien, simplemente agregar un paréntesis a continuación, o no utilizan por completo - después de todo, es un hecho bien conocido que los operadores ternarios son malos

!

Por supuesto que son, pero hay algunas circunstancias en las que realmente tienen sentido. Para los curiosos - Estoy exprimir código que compara dos objetos por una serie de propiedades. Sería muy bueno si frío de agua escribir así:

obj1.Prop1 != obj2.Prop1 ? obj1.Prop1.CompareTo(obj2.Prop1) :
obj1.Prop2 != obj2.Prop2 ? obj1.Prop2.CompareTo(obj2.Prop2) :
obj1.Prop3 != obj2.Prop3 ? obj1.Prop3.CompareTo(obj2.Prop3) :
obj1.Prop4.CompareTo(obj2.Prop4)

Claro y conciso. Pero esto depende de la asociatividad operador ternario de trabajo como en el primer caso. Paréntesis acaba de hacer espaguetis fuera de él.

Por lo tanto - se especifica esta en cualquier lugar? No pude encontrarlo.

¿Fue útil?

Solución

Sí, se puede confiar en esta (no sólo en C #, pero en todos (que yo sepa) otros idiomas ( excepto PHP ... que figura) con un operador condicional) y el caso de uso es en realidad una práctica bastante común, aunque algunas personas aborrecen.

La sección pertinente en ECMA-334 (el # estándar C) es 14,13 §3:

  

El operador condicional es asociativo por la derecha, lo que significa que las operaciones se agrupan de derecha a izquierda.   [Ejemplo: Una expresión de la forma a ? b : c ? d : e se evalúa como a ? b : (c ? d : e). fin   ejemplo]

Otros consejos

Si usted tiene que pedir, no lo hacen. Cualquiera que lea el código sólo tendrá que pasar por el mismo proceso que hizo, una y otra vez, cualquier tiempo necesita que el código a ser mirado. La depuración de tal código no es divertido. Con el tiempo se acaba de ser cambiado a utilizar paréntesis de todos modos.

Re: "Trate de escribir todo el asunto con paréntesis"

result = (obj1.Prop1 != obj2.Prop1 ? obj1.Prop1.CompareTo(obj2.Prop1) :
         (obj1.Prop2 != obj2.Prop2 ? obj1.Prop2.CompareTo(obj2.Prop2) :
         (obj1.Prop3 != obj2.Prop3 ? obj1.Prop3.CompareTo(obj2.Prop3) :
                                     obj1.Prop4.CompareTo(obj2.Prop4))))

Aclaración:

  • "Si tiene que pedir, no lo hacen."
  • "Cualquiera que lea su código ..."

Siguiendo las convenciones comunes en un proyecto es la forma de mantener la coherencia, lo que mejora la legibilidad. Sería una tontería pensar que se puede escribir código legible para todos, incluso los que ni siquiera conocen el idioma!

Mantener la consistencia dentro de un proyecto, sin embargo, es un objetivo útil, y no seguir las convenciones aceptadas de un proyecto conduce a debate que resta valor a la solución del problema real. Se espera que aquellos de leer su código para estar al tanto de las convenciones comunes y aceptados utilizados en el proyecto, y son incluso probable que sea otra persona que trabaja directamente sobre ella. Si no saben ellos, entonces se espera que estén aprendiendo de ellos y deben saber a dónde acudir en busca de ayuda.

Dicho esto, si el uso de expresiones ternarias sin paréntesis es una convención común y aceptado en su proyecto, entonces usarlo, por todos los medios! Que tienes que pedir indica que no es común o aceptado en su proyecto. Si desea cambiar las convenciones en su proyecto, a continuación, hacer lo obvio sin ambigüedades, marcarlo como algo que discutir con otros miembros del proyecto, y seguir adelante. Aquí eso significa que el uso de paréntesis, o el uso de if-else.

Un último punto a reflexionar, si algunos de su código parece inteligente para usted:

  

La depuración es dos veces más duro que escribir el código en el primer lugar. Por lo tanto, si se escribe el código lo más inteligentemente posible, usted es, por definición, no lo suficientemente inteligente para depurarlo. - Brian W. Kernighan

La afirmación de que los paréntesis en detrimento de la legibilidad del código es una suposición falsa. Me parece la expresión entre paréntesis mucho más clara. En lo personal, me gustaría utilizar los paréntesis y / o volver a formatear en varias líneas para mejorar la legibilidad. Cambio de formato largo de varias líneas y el uso de la sangría, incluso puede obviar la necesidad de paréntesis. Y, sí, puede confiar en el hecho de que el orden de asociación es determinista, de derecha a izquierda. Esto permite la expresión para evaluar izquierda a derecha de la manera esperada.

obj1.Prop1 != obj2.Prop1
     ? obj1.Prop1.CompareTo(obj2.Prop1)
     : obj1.Prop2 != obj2.Prop2
           ? obj1.Prop2.CompareTo(obj2.Prop2)
           : obj1.Prop3 != obj2.Prop3
                  ? obj1.Prop3.CompareTo(obj2.Prop3)
                  : obj1.Prop4.CompareTo(obj2.Prop4);

Consulte MSDN: http://msdn.microsoft.com/en- es / library / ty67wk28% 28VS.80% 29.aspx

"Si la condición es verdadera, primera expresión se evalúa y se convierte en el resultado;.. Si es falso, se evalúa la segunda expresión y se convierte en el resultado sólo una de las dos expresiones se evalúa siempre"

x = cond1 ? result1
  : cond2 ? result2
  : cond3 ? result3
  : defaultResult;

vs

if (cond1) x = result1;
else if (cond2) x = result2;
else if (cond3) x = result3;
else x = defaultResult;

Me gusta la primera.

Sí, puede depender de la asociatividad operador condicional. Está en el manual, en el enlace proporcionado amablemente por el DCP, declaró como "El operador condicional es asociativo por la derecha", con un ejemplo. Y, como usted sugiere, yo y otros estuvieron de acuerdo, el hecho de que se puede confiar en ella permite que el código más claro.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top