Note
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier les répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de changer de répertoire.
Remarque
Cet article est une spécification de fonctionnalité. La spécification sert de document de conception pour la fonctionnalité. Elle inclut les changements de spécification proposés, ainsi que les informations nécessaires à la conception et au développement de la fonctionnalité. Ces articles sont publiés jusqu'à ce que les changements proposés soient finalisés et incorporés dans la spécification ECMA actuelle.
Il peut y avoir des différences entre la spécification de la fonctionnalité et l'implémentation réalisée. Ces différences sont consignées dans les notes pertinentes de la réunion de conception linguistique (LDM).
Pour en savoir plus sur le processus d'adoption des speclets de fonctionnalité dans la norme du langage C#, consultez l'article sur les spécifications.
Problème de champion : https://github.com/dotnet/csharplang/issues/2460
Conversion d’une expression conditionnelle
Pour une expression conditionnelle c ? e1 : e2, quand
- il n’existe aucun type commun pour
e1ete2, ou - pour laquelle un type commun existe, mais l’une des expressions
e1oue2n’a pas de conversion implicite en ce type
nous définissons une nouvelle conversion d’expression conditionnelle implicite qui permet une conversion implicite de l’expression conditionnelle en n’importe quel type T pour lequel il existe une conversion à partir de l’expression de e1 en T et aussi de e2 en T. Si une expression conditionnelle n’a pas de type commun entre e1 et e2 et n’est pas soumise à une conversion d’expression conditionnelle, il s’agit d’une erreur.
Meilleure conversion à partir de l'expression
Nous changeons
Meilleure conversion à partir de l’expression
Étant donné une conversion implicite
C1qui convertit d’une expressionEen un typeT1, et une conversion impliciteC2qui convertit d’une expressionEen un typeT2,C1est une meilleure conversion queC2siEne correspond pas exactementT2et au moins l’une des conditions suivantes :
à
Meilleure conversion à partir de l’expression
Étant donné une conversion implicite
C1qui convertit d’une expressionEen un typeT1, et une conversion impliciteC2qui convertit d’une expressionEen un typeT2,C1est une meilleure conversion queC2siEne correspond pas exactementT2et au moins l’une des conditions suivantes :
Ecorrespond exactement àT1(§12.6.4.5)C1n’est pas une conversion d’expression conditionnelle etC2est une conversion d’expression conditionnelle.T1est une meilleure cible de conversion queT2(§12.6.4.7) et soitC1etC2sont toutes deux des conversions d'expressions conditionnelles, soit aucune n'est une conversion d'expression conditionnelle.
Expression coulée
La spécification actuelle du langage C# indique
Une cast_expression de la forme
(T)E, oùTest un type etEune unary_expression, effectue une conversion explicite (§10.3) de la valeur deEvers le typeT.
En présence de la conversion d’expression conditionnelle, il peut y avoir plusieurs conversions possibles de E en T. Avec l’ajout de la conversion d'expression conditionnelle , nous préférons une autre conversion à une conversion d'expression conditionnelle , et utilisons la conversion d'expression conditionnelle uniquement en dernier recours.
Notes de conception
La raison du changement pour une meilleure conversion à partir d'une expression est de traiter un cas comme celui-ci :
M(b ? 1 : 2);
void M(short);
void M(long);
Cette approche présente deux petits inconvénients. Tout d’abord, ce n’est pas tout à fait la même chose que l’expression switch :
M(b ? 1 : 2); // calls M(long)
M(b switch { true => 1, false => 2 }); // calls M(short)
Il s’agit toujours d’un changement cassant, mais son étendue est moins susceptible d’affecter les programmes réels :
M(b ? 1 : 2, 1); // calls M(long, long) without this feature; ambiguous with this feature.
M(short, short);
M(long, long);
Il y a ambiguïté, car la conversion en long est meilleure pour le premier argument (parce qu’elle n’utilise pas la conversion d’expression conditionnelle), mais la conversion en short est meilleure pour le deuxième argument (parce que short est une meilleure cible de conversion que long). Ce changement de rupture semble moins préoccupant, car il ne modifie pas silencieusement le comportement d’un programme existant.
La raison des notes sur l'expression cast est de traiter un cas comme celui-ci :
_ = (short)(b ? 1 : 2);
Ce programme utilise actuellement la conversion explicite de int en short, et nous voulons conserver la signification actuelle du langage de ce programme. Le changement ne serait pas observable au moment de l’exécution, mais avec le programme suivant, il le serait :
_ = (A)(b ? c : d);
où c est de type C, d est de type D, et il existe une conversion implicite définie par l’utilisateur de C en D, et une conversion implicite définie par l’utilisateur de D en A, et une conversion implicite définie par l’utilisateur de C en A. Si ce code est compilé avant C# 9.0, lorsque b est vrai, nous convertissons de c en D puis en A. Si nous utilisons la conversion d'expression conditionnelle , alors, lorsque b est vrai, nous convertissons directement de c à A, ce qui exécute une séquence différente de code utilisateur. Par conséquent, nous traitons la conversion d'expression conditionnelle en dernier recours dans un cast, afin de préserver le comportement existant.
C# feature specifications