Esto está prácticamente cubierto por las otras respuestas, pero "es una expresión" realmente no explica por qué es tan útil ...
En lenguajes como C ++ y C #, puede definir campos de solo lectura locales (dentro del cuerpo de un método) usándolos. Esto no es posible con una declaración if / then convencional porque el valor de un campo de solo lectura debe asignarse dentro de esa declaración única:
readonly int speed = (shiftKeyDown) ? 10 : 1;
no es lo mismo que:
readonly int speed;
if (shifKeyDown)
speed = 10; // error - can't assign to a readonly
else
speed = 1; // error
De manera similar, puede incrustar una expresión terciaria en otro código. Además de hacer que el código fuente sea más compacto (y en algunos casos más legible como resultado), también puede hacer que el código máquina generado sea más compacto y eficiente:
MoveCar((shiftKeyDown) ? 10 : 1);
... puede generar menos código que tener que llamar al mismo método dos veces:
if (shiftKeyDown)
MoveCar(10);
else
MoveCar(1);
Por supuesto, también es una forma más conveniente y concisa (menos escritura, menos repetición y puede reducir la posibilidad de errores si tiene que duplicar fragmentos de código en un if / else). En casos limpios de "patrón común" como este:
object thing = (reference == null) ? null : reference.Thing;
... es simplemente más rápido de leer / analizar / comprender (una vez que esté acostumbrado) que el equivalente if / else de largo aliento, por lo que puede ayudarlo a 'asimilar' el código más rápido.
Por supuesto, el hecho de que sea útil no significa que sea lo mejor para usar en todos los casos. Aconsejaría usarlo solo para fragmentos cortos de código donde el significado es claro (o se aclara más) al usarlo ?:
: si lo usa en un código más complejo, o anida operadores ternarios entre sí, puede hacer que el código sea terriblemente difícil de leer .