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 dynamic
reliure. 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, x
et ce y
n'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, x
est true
et y
est null
.
Mais l'évaluation de xx
of A || B
conduit à 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 B
getter pour renvoyer un objet fou, comme "Hello world"
, et xx
nous évaluerions toujours true
sans 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 B
est 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 B
tant que premier opérande, les deux B || A
et B && A
donnent une exception de reliure d'exécution ( B | A
et B & A
fonctionnent 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.)