Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
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 y 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 especificaciones.
Problema planteado por el experto: https://github.com/dotnet/csharplang/issues/2460
Conversión de expresiones condicionales
Para una expresión condicional c ? e1 : e2, cuando
- no existe un tipo común para
e1ye2o - para la que existe un tipo común pero una de las expresiones
e1oe2no tiene 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. Es un error si una expresión condicional ni tiene un tipo común entre e1 y e2 ni está sujeta 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
C1que convierte de una expresiónEa un tipoT1y una conversión implícitaC2que convierte de una expresiónEa un tipoT2,C1es una mejor conversión queC2siEno coincide exactamente conT2y se cumple al menos una de las siguientes condiciones:
Ecoincide exactamente conT1(Sección 12.6.4.5)T1es un objetivo de conversión mejor queT2(Sección 12.6.4.7)
to
Mejor conversión a partir de expresión
Dada una conversión implícita
C1que convierte de una expresiónEa un tipoT1y una conversión implícitaC2que convierte de una expresiónEa un tipoT2,C1es una mejor conversión queC2siEno coincide exactamente conT2y se cumple al menos una de las siguientes condiciones:
Ecoincide exactamente conT1(Sección 12.6.4.5)C1no es una conversión de expresión condicional yC2es una conversión de expresión condicional.T1es un destino de conversión mejor queT2(§12.6.4.7) y tantoC1comoC2son 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# dice
Una cast_expression con el formato
(T)E, dondeTes un tipo yEes una unary_expression, realiza una conversión explícita (§10.3) del valor deEal 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ños inconvenientes. 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)
Sigue siendo un cambio de ruptura, pero su alcance 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 vuelve ambiguo porque la conversión a long es mejor para el primer argumento (porque no utiliza la conversión de expresión condicional), pero la conversión a short es mejor para el segundo argumento (porque short es un mejor objetivo de conversión 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);
Este programa utiliza actualmente la conversión explícita de int a short, y queremos preservar el significado lingüístico actual de este programa. El cambio sería inobservable 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