J'ai lu la spécification du langage C # sur les opérateurs logiques conditionnels || et &&, également connus sous le nom d'opérateurs logiques de court-circuit. Pour moi, il ne semblait pas clair si ceux-ci existaient pour les booléens nullables, c'est-à-dire le type d'opérande Nullable<bool>(également écrit bool?), alors je l'ai essayé avec un typage non dynamique:
bool a = true;
bool? b = null;
bool? xxxx = b || a; // compile-time error, || can't be applied to these types
Cela semblait régler la question (je ne pouvais pas comprendre clairement la spécification, mais en supposant que l'implémentation du compilateur Visual C # était correcte, je le savais maintenant).
Cependant, je voulais aussi essayer la dynamicreliure. J'ai donc essayé ceci à la place:
static class Program
{
static dynamic A
{
get
{
Console.WriteLine("'A' evaluated");
return true;
}
}
static dynamic B
{
get
{
Console.WriteLine("'B' evaluated");
return null;
}
}
static void Main()
{
dynamic x = A | B;
Console.WriteLine((object)x);
dynamic y = A & B;
Console.WriteLine((object)y);
dynamic xx = A || B;
Console.WriteLine((object)xx);
dynamic yy = A && B;
Console.WriteLine((object)yy);
}
}
Le résultat surprenant est que cela fonctionne sans exception.
Eh bien, xet ce yn'est pas surprenant, leurs déclarations conduisent à la récupération des deux propriétés et les valeurs résultantes sont comme prévu, xest trueet yest null.
Mais l'évaluation de xxof A || Bconduit à aucune exception de temps de liaison, et seule la propriété a Aété lue, non B. Pourquoi cela arrive-t-il? Comme vous pouvez le voir, nous pourrions changer le Bgetter pour renvoyer un objet fou, comme "Hello world", et xxnous évaluerions toujours truesans problèmes de liaison ...
L'évaluation A && B(pour yy) ne conduit également à aucune erreur de temps de liaison. Et ici, les deux propriétés sont récupérées, bien sûr. Pourquoi est-ce autorisé par le classeur d'exécution? Si l'objet renvoyé de Best changé en un objet "incorrect" (comme a string), une exception de liaison se produit.
Ce comportement est-il correct? (Comment pouvez-vous déduire cela de la spécification?)
Si vous essayez en Btant que premier opérande, les deux B || Aet B && Adonnent une exception de reliure d'exécution ( B | Aet B & Afonctionnent correctement car tout est normal avec des opérateurs sans court-circuit |et &).
(Essayé avec le compilateur C # de Visual Studio 2013 et la version d'exécution .NET 4.5.2.)
Nullable<Boolean>impliqué du tout, seuls les booléens encadrés sont traités commedynamic- votre test avecbool?n'est pas pertinent. (Bien sûr, ce n'est pas une réponse complète, seulement le germe d'une.)