74 votes

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?

87voto

JLRishe Points 22173

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

Le type de l'expression b == c ? 0 : 1 est int. Comme le montre ce tableau, il n'y a pas de conversion implicite de int de uint, donc ce n'est pas autorisé.

Pourquoi puis-je utiliser a = 0?

Car il y a un traitement spécial des types numériques, lorsque la valeur est une expression constante.

De l'article 6.1.9 de la spécification C#:

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

  • Une expression constante de type long peut-être convertie en type ulong, à condition que la valeur de la constante d'expression n'est pas négatif.

Comme indiqué dans la première puce a = 0 et a = 1 sont à la fois autorisée, car 0 et 1 sont des expressions constantes et sont valides uint valeurs. Fondamentalement, ce que cela se résume au fait que le compilateur peut déterminer facilement au moment de la compilation que ces conversions sont valides, de sorte qu'il permet.

Par ailleurs, si l' b == c le cadre de votre premier exemple a été modifié pour la une expression constante (par exemple, true), puis l'ensemble de l'opérateur conditionnel expression est une expression constante et le code à compiler.

26voto

Damien_The_Unbeliever Points 102139

Si b==c ont une expression constante alors l'ensemble de l'opérateur conditionnel serait considérée comme une expression constante et donc, ensuite, la règle permettant des expressions constantes de type int à être convertis en d'autres int types s'appliquent et il serait procédé.

De toute évidence, b==c n'est pas une expression constante et donc le résultat de l'opérateur conditionnel ne peut être connu que de l'exécution et donc la dispense qui permet une conversion implicite d'entiers à uint (pour les expressions constantes) ne s'applique pas.

Dans votre if/else variante, à la fois du réel affectations sont des expressions constantes.

10voto

teo van kot Points 3477

Vous devez utiliser des littéraux pour que votre code fonctionne correctement de la manière suivante:

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X