web-dev-qa-db-fra.com

Pourquoi?: Provoque une erreur de conversion alors que si ne le fait pas?

En apportant quelques modifications au code, j'utilise la ligne suivante:

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

Visual Studio me montre cette erreur:

Impossible de convertir implicitement le type 'int' en 'uint'. Une conversion explicite existe (manque-t-il un casting?)

Mais si j'utilise le code:

uint a; 

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

Cela fonctionne correctement sans aucune erreur ou avertissement. Pourquoi?

74
Ruben Aguilar

Pourquoi ne puis-je pas utiliser uint a = b == c ? 0 : 1;?

Le type de l'expression b == c ? 0 : 1 est int. Comme indiqué dans cette table , il n'y a pas de conversion implicite de int en uint, donc ceci n'est pas autorisé.

Pourquoi puis-je utiliser a = 0?

Parce qu'il existe un traitement spécial des types numériques lorsque la valeur est une expression constante.

À partir de la section 6.1.9 de la spécification C #:

  • Une expression constante de type int peut être convertie en type sbyte, octet, court, ushort, uint ou ulong, à condition que la valeur de l'expression constante soit dans la plage du type de destination.

  • Une expression constante de type long peut être convertie en type ulong, à condition que la valeur de l'expression constante ne soit pas négative.

Comme indiqué dans la première puce a = 0 et a = 1 sont tous deux autorisés car 0 et 1 sont des expressions constantes et valides uint valeurs. En gros, cela revient au fait que le compilateur peut facilement déterminer, au moment de la compilation, que ces conversions sont valides et qu’elles le permettent.

Incidemment, si le b == c une partie de votre premier exemple a été modifiée en une expression constante (par exemple, true), alors l'expression entière de l'opérateur conditionnel serait une expression constante et le code serait compilé.

87
JLRishe

Sib==c était une expression constante, alors l’opérateur conditionnel entier serait considéré comme une expression constante. Ainsi, la règle permettant aux expressions constantes de type int d’être converties en d’autres types int s’appliquerait et se compilerait.

Évidemment, b==c n'est pas une expression constante. Par conséquent, le résultat de l'opérateur conditionnel ne peut être connu qu'au moment de l'exécution. L'exemption qui autorise une conversion implicite des entiers en uint (pour les expressions constantes) ne s'applique pas.

Dans votre variante if/else, , les deux des affectations réelles sont des expressions constantes.

26

Vous devriez utiliser littéraux pour que votre code fonctionne correctement comme ceci:

uint a = b == c ? 0U : 1U;
10
teo van kot