Pourquoi cela ne compile-t-il pas?
int? number = true ? 5 : null;
Le type d'expression conditionnelle ne peut pas être déterminé car il n'y a pas de conversion implicite entre 'int' et <null>
La spécification (§7.14) dit que pour l'expression conditionnelle b ? x : y
, il y a trois possibilités, soit x
et y
ont tous les deux un type et certain bonnes conditions sont remplies , un seul de x
et y
a un type et certain bonnes conditions sont remplies, ou un temps de compilation erreur se produit. Ici, "certaines bonnes conditions" signifie que certaines conversions sont possibles, nous allons entrer dans les détails ci-dessous.
Passons maintenant à la partie germane de la spécification:
Si un seul de
x
ety
a un type et quex
ety
sont implicitement convertibles en ce type, il s'agit du type de la expression conditionnelle.
Le problème ici est que dans
int? number = true ? 5 : null;
un seul des résultats conditionnels a un type. Ici x
est un int
littéral, et y
est null
ce qui pas a un type et null
ne peut pas être converti implicitement en un int
1. Par conséquent, "certaines bonnes conditions" ne sont pas remplies et une erreur lors de la compilation se produit.
Il y a sont deux manières de contourner cela:
int? number = true ? (int?)5 : null;
Nous sommes toujours dans le cas où un seul de x
et y
a un type. Notez que null
encore n'a pas de type, mais le compilateur n'aura aucun problème avec cela car (int?)5
et null
sont tous deux implicitement convertibles en int?
(§ 6.1.4 et 6.1.5).
L'autre façon est évidemment:
int? number = true ? 5 : (int?)null;
mais maintenant, nous devons lire une clause différente dans la spécification pour comprendre pourquoi cela est acceptable:
Si
x
a le typeX
ety
a le typeY
alors
Si une conversion implicite (§6.1) existe de
X
enY
, mais pas deY
àX
, alorsY
est le type de l'expression conditionnelle.Si une conversion implicite (§6.1) existe de
Y
enX
, mais pas deX
àY
, alorsX
est le type de l'expression conditionnelle.Sinon, aucun type d'expression ne peut être déterminé et une erreur de compilation se produit.
Ici x
est de type int
et y
est de type int?
. Il n'y a pas de conversion implicite de int?
à int
, mais il existe une conversion implicite de int
à int?
donc le type de l'expression est int?
.
1Remarque: notez également que le type du côté gauche est ignoré lors de la détermination du type de l'expression conditionnelle, source de confusion commune ici.
null
n'a pas de type identifiable - il a juste besoin d'un petit coup de pouce pour le rendre heureux:
int? number = true ? 5 : (int?)null;