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
- no hay ningún tipo común para
e1
ye2
, o - para el que existe un tipo común, pero una de las expresiones
e1
oe2
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ónE
a un tipoT1
y una conversión implícitaC2
que convierte de una expresiónE
a un tipoT2
,C1
es una mejor conversión queC2
siE
no coincide exactamente conT2
y se cumple al menos una de las siguientes condiciones:
to
Mejor conversión a partir de expresión
Dada una conversión implícita
C1
que convierte de una expresiónE
a un tipoT1
, y una conversión implícitaC2
que convierte de una expresiónE
a un tipoT2
,C1
es una mejor conversión queC2
siE
no coincide exactamente conT2
y al menos una de las siguientes condiciones:
E
coincide exactamente conT1
(§12.6.4.5)C1
no es una conversión de expresión condicional yC2
es una conversión de expresión condicional.T1
es un destino de conversión mejor queT2
(§12.6.4.7) y tantoC1
comoC2
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
, dondeT
es un tipo yE
es una unary_expression, realiza una conversión explícita (§10.3) del valor deE
al tipoT
.
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 D
y 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 A
y 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.
C# feature specifications