Compartir vía


Target-Typed Expresión Condicional

Nota

Este artículo es una especificación de características. La especificación actúa como documento de diseño de la característica. Incluye cambios de especificación propuestos, junto con la información necesaria durante el diseño y el desarrollo de la característica. Estos artículos se publican hasta que se finalizan los cambios de especificación propuestos e se incorporan en la especificación ECMA actual.

Puede haber algunas discrepancias entre la especificación de características y la implementación completada. Esas diferencias se recogen en las notas de la reunión de diseño de lenguaje (LDM) correspondientes.

Puede obtener más información sobre el proceso de adopción de especificaciones de características en el estándar del lenguaje C# en el artículo sobre las especificaciones de .

Conversión de expresiones condicionales

Para una expresión condicional c ? e1 : e2, cuando

  1. no hay ningún tipo común para e1 y e2, o
  2. para el que existe un tipo común, pero una de las expresiones e1 o e2 no tiene ninguna conversión implícita a ese tipo

definimos una nueva conversión de expresión condicional implícita que permite una conversión implícita de la expresión condicional a cualquier tipo T para la cual existe una conversión desde la expresión de e1 a T, así como de e2 a T. Se trata de un error si una expresión condicional no tiene un tipo común entre e1 y e2 ni está sujeto a una conversión de expresión condicional .

Mejor conversión a partir de expresión

Cambiamos

Mejor conversión a partir de expresión

Dada una conversión implícita C1 que convierte de una expresión E a un tipo T1y una conversión implícita C2 que convierte de una expresión E a un tipo T2, C1 es una mejor conversión que C2 si E no coincide exactamente con T2 y se cumple al menos una de las siguientes condiciones:

  • E coincide exactamente con T1 (§12.6.4.5)
  • T1 es un destino de conversión mejor que T2 (§12.6.4.7)

to

Mejor conversión a partir de expresión

Dada una conversión implícita C1 que convierte de una expresión E a un tipo T1, y una conversión implícita C2 que convierte de una expresión E a un tipo T2, C1 es una mejor conversión que C2 si E no coincide exactamente con T2 y al menos una de las siguientes condiciones:

  • E coincide exactamente con T1 (§12.6.4.5)
  • C1 no es una conversión de expresión condicional y C2 es una conversión de expresión condicional.
  • T1 es un destino de conversión mejor que T2 (§12.6.4.7) y tanto C1 como C2 son conversiones de expresión condicional o ninguno es una conversión de expresión condicional.

Expresión de conversión

La especificación actual del lenguaje C# indica

Una cast_expression con el formato (T)E, donde T es un tipo y E es una unary_expression, realiza una conversión explícita (§10.3) del valor de E al tipo T.

En presencia de la conversión de expresión condicional puede haber más de una posible conversión de E a T. Con la adición de la conversión de expresiones condicionales, preferimos cualquier otra conversión a una conversión de expresión condicional y utilizamos la conversión de expresión condicional solo como último recurso.

Notas de diseño

El motivo del cambio a una mejor conversión de la expresión es para manejar un caso como este:

M(b ? 1 : 2);

void M(short);
void M(long);

Este enfoque tiene dos pequeñas desventajas. En primer lugar, no es exactamente lo mismo que la expresión switch.

M(b ? 1 : 2); // calls M(long)
M(b switch { true => 1, false => 2 }); // calls M(short)

Esto sigue siendo un cambio importante, pero su ámbito es menos probable que afecte a los programas reales:

M(b ? 1 : 2, 1); // calls M(long, long) without this feature; ambiguous with this feature.

M(short, short);
M(long, long);

Esto se convierte en ambiguo porque la conversión a long es mejor para el primer argumento (porque no usa la conversión de expresión condicional ), pero la conversión a short es mejor para el segundo argumento (porque short es un destino de conversión mejor que long). Este cambio rompedor parece menos grave porque no cambia silenciosamente el comportamiento de un programa existente.

El motivo de las notas de la expresión de conversión es manejar un caso como el siguiente:

_ = (short)(b ? 1 : 2);

Actualmente, este programa usa la conversión explícita de int a short, y queremos conservar el significado actual del lenguaje de este programa. El cambio sería inobservible en tiempo de ejecución, pero con el siguiente programa, el cambio sería observable:

_ = (A)(b ? c : d);

donde c es de tipo C, d es de tipo Dy hay una conversión implícita definida por el usuario de C a D, y una conversión implícita definida por el usuario de D a Ay una conversión implícita definida por el usuario de C a A. Si este código se compila antes de C# 9.0, cuando b es verdadero, convertimos de c a D y luego a A. Si usamos la conversión de expresiones condicionales, entonces, cuando b es verdadero, convertimos de c a A directamente y ejecutamos una secuencia diferente de código de usuario. Por lo tanto, consideramos la conversión de expresión condicional como último recurso al realizar una conversión, para conservar el comportamiento existente.