Ich habe die C # -Sprachenspezifikation für die bedingten logischen Operatoren gelesen ||
und &&
auch als kurzschließende logische Operatoren bezeichnet. Für mich schien es unklar, ob diese für nullfähige Boolesche Werte existieren, dh für den Operandentyp Nullable<bool>
(ebenfalls geschrieben bool?
), also habe ich es mit nicht dynamischer Typisierung versucht:
bool a = true;
bool? b = null;
bool? xxxx = b || a; // compile-time error, || can't be applied to these types
Das schien die Frage zu klären (ich konnte die Spezifikation nicht klar verstehen, aber vorausgesetzt, die Implementierung des Visual C # -Compilers war korrekt, jetzt wusste ich es).
Ich wollte es aber auch mit dynamic
Bindung versuchen . Also habe ich stattdessen versucht:
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);
}
}
Das überraschende Ergebnis ist, dass dies ausnahmslos läuft.
Nun, x
und y
es ist nicht überraschend, dass ihre Deklarationen dazu führen, dass beide Eigenschaften abgerufen werden und die resultierenden Werte wie erwartet sind, x
sind true
und y
sind null
.
Aber die Auswertung für xx
von A || B
Blei zu keiner Bindung einmaligen Ausnahme und nur die Eigenschaft A
gelesen wurden, nicht B
. Warum passiert das? Wie Sie sehen können, könnten wir den B
Getter so ändern , dass er ein verrücktes Objekt zurückgibt "Hello world"
, und xx
würden es trotzdem true
ohne Bindungsprobleme auswerten ...
Das Auswerten A && B
(für yy
) führt auch zu keinem Bindungszeitfehler. Und hier werden natürlich beide Eigenschaften abgerufen. Warum ist dies durch den Laufzeitbinder zulässig? Wenn das zurückgegebene Objekt von B
in ein "fehlerhaftes" Objekt (wie a string
) geändert wird , tritt eine verbindliche Ausnahme auf.
Ist das richtig? (Wie können Sie das aus der Spezifikation ableiten?)
Wenn Sie es B
als ersten Operanden versuchen , geben Sie beide aus B || A
und B && A
geben eine Laufzeitbinder-Ausnahme aus ( B | A
und B & A
funktionieren einwandfrei, da bei nicht kurzgeschlossenen Operatoren |
und normal alles normal ist &
).
(Versucht mit dem C # -Compiler von Visual Studio 2013 und der Laufzeitversion .NET 4.5.2.)
Nullable<Boolean>
Beteiligung, nur Boxed Booleans, die als behandelt werdendynamic
- Ihr Test mitbool?
ist irrelevant. (Natürlich ist dies keine vollständige Antwort, nur der Keim von einem.)