Ceci est défini par la spécification du langage C#, bien sûr.
Ce qu'il faut savoir, c'est qu'il existe deux types de conversions. de int
à short
. L'un est un explicite conversion qui s'applique toujours mais qui nécessite d'écrire (short)
explicitement avant le int
expression. L'autre est une conversion d'une expression constante implicite qui ne s'applique que lorsque (a) le site int
est une constante de temps de compilation et (b) la valeur de cette expression du temps de compilation est comprise dans l'intervalle d'un short
c'est-à-dire -32768
par le biais de 32767
.
Un littéral comme 5
, 10
o 4
a un type int
en C# (cela s'applique à tout entier littéral qui se trouve entre -2147483648
y 2147483647
et non suivi d'un symbole L
, U
ou similaire). Ainsi, si nous regardons les côtés droits de toutes vos missions, ils sont clairement int
des expressions, et non short
.
Dans l'affaire 10 > 4 ? 5 : 10
puisque 10
y 4
sont des constantes de compilation, c'est la même chose que true ? 5 : 10
parce que le >
opérateur entre int
s est intégré et donnera une constante lorsque les opérandes sont des constantes. Et de la même manière true ? 5 : 10
donne 5
car les trois opérandes sont des constantes, et ?:
est classé lui-même comme une constante dans ce cas. Donc ça dit vraiment :
short value = 5;
où le " 5
"est une constante de compilation. Par conséquent, il est vérifié au moment de la compilation si l'élément int
5
se situe dans la fourchette (cela n'a pas d'importance avec l'option 10
il pourrait être 999999
), et puisque c'est le cas, l'option conversion d'une expression constante implicite s'applique, et c'est légal.
Notez que vous pouvez faire la même chose avec :
const int huge = 10;
const int tiny = 4;
const int significant = 5;
const int unimporatnt = 10;
short value;
value = huge > tiny ? significant : unimportant;
tant que tous les opérandes sont const
variables (jeu de mots ?).
Maintenant, si j'ai réussi à rendre l'explication claire, vous savez aussi maintenant que l'obstacle empêchant value = "test" == str ? 5 : 10;
de fonctionner est que vous n'avez pas marqué le str
local comme const
. Faites-le, et il sera autorisé.
Avec le Equals
la situation est un peu plus grave. Le résultat d'un appel à Equals
n'est jamais considérée comme une constante de temps de compilation (et je ne pense pas qu'elle soit "optimisée" loin de là, par exemple "same".Equals("same")
appellera effectivement la méthode au moment de l'exécution). La même chose se produirait avec (10).Equals(4)
o (10).CompareTo(4) > 0
et ainsi de suite, les cordes ne sont donc pas spéciales à cet égard.
Vous savez probablement déjà que lorsque
short value = cond ? 5 : 10;
n'est pas autorisé car cond
n'est pas une constante de temps de compilation, vous utilisez simplement la conversion explicite à la place, donc écrivez :
short value = cond ? (short)5 : (short)10;
ou :
short value = (short)(cond ? 5 : 10);
Techniquement, ils ne sont pas identiques, puisque le premier n'a pas de conversion de restriction au moment de l'exécution (les expressions (short)5
y (short)10
sont des littéraux de type short
), tandis que le dernier doit convertir un fichier int
a short
au moment de l'exécution (ce qui est bien sûr moins cher qu'incroyablement bon marché).
Les autres réponses (non supprimées !) sont correctes, ce n'est qu'une information supplémentaire.