web-dev-qa-db-fra.com

Le type d'expression conditionnelle ne peut pas être déterminé car il n'y a pas de conversion implicite entre 'int' et <null>

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>

135
davidhq

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 et y a un type et que x et y 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 int1. 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 type X et y a le type Y alors

  • Si une conversion implicite (§6.1) existe de X en Y, mais pas de Y à X, alors Y est le type de l'expression conditionnelle.

  • Si une conversion implicite (§6.1) existe de Y en X, mais pas de X à Y, alors X 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.

279
jason

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;
62
Marc Gravell