Pregunta ¿Por qué?: ¿Causa un error de conversión mientras que if-else no? [duplicar]


Esta pregunta ya tiene una respuesta aquí:

Haciendo algunos cambios en el código, uso la siguiente línea:

uint a = b == c ? 0 : 1;

Visual Studio me muestra este error:

No se puede convertir implícitamente el tipo 'int' a 'uint'. Existe una conversión explícita (¿falta un elenco?)

Pero si uso el código:

uint a; 

if (b == c) 
    a = 0; 
else 
    a = 1;

Funciona correctamente sin ningún error o advertencia. ¿Por qué?


75
2018-03-09 08:18


origen


Respuestas:


Por qué no puedo usar uint a = b == c ? 0 : 1;?

El tipo de la expresión b == c ? 0 : 1 es int. Como se muestra en Esta mesa, no hay conversión implícita de int a uint, entonces esto no está permitido.

Por qué puedo usar a = 0?

Porque hay un tratamiento especial de los tipos numéricos cuando el valor es una expresión constante.

De la sección 6.1.9 de la especificación C #:

  • Una expresión constante de tipo int se puede convertir a tipo sbyte, byte, short, ushort, uint o ulong, siempre que el valor de la expresión constante esté dentro del rango del tipo de destino.

  • Una expresión constante de tipo long se puede convertir a tipo ulong, siempre que el valor de la expresión constante no sea negativo.

Como se indica en la primera viñeta a = 0 y a = 1 ambos son permitidos porque 0 y 1 son expresiones constantes y son válidas uint valores. Básicamente, esto se reduce a que el compilador puede determinar fácilmente en tiempo de compilación que estas conversiones son válidas, por lo que las permite.

Por cierto, si el b == c parte de su primer ejemplo se cambió a una expresión constante (p. true), entonces toda la expresión de operador condicional sería una expresión constante y el código se compilaría.


87
2018-03-09 08:27



Si  b==c eran una expresión constante, entonces todo el operador condicional se consideraría una expresión constante y entonces, la regla permite expresiones constantes de tipo int para convertir a otros tipos int se aplicaría y se compilaría.

Obviamente, b==c no es una expresión constante y, por lo tanto, el resultado del operador condicional no se puede conocer hasta el tiempo de ejecución y, por lo tanto, no se aplica la exención que permite una conversión implícita de ints a uint (para expresiones constantes).

En tus if/else variante, ambos de las asignaciones reales son expresiones constantes.


26
2018-03-09 08:28



Deberías usar literales para hacer que tu código funcione correctamente así:

uint a = b == c ? 0U : 1U;

10
2018-03-09 08:22