Nehmen Sie Kurzschlüsse an den Bedienern vor || und && existieren für nullbare Boolesche Werte? Der RuntimeBinder denkt manchmal so
Ich habe die C # -Sprachenspezifikation auf dem @ gelese Bedingte logische Operatoren ||
und&&
, auch als logische Kurzschlussoperatoren bekannt. Für mich schien es unklar, ob es diese für nullbare Boolesche Werte gibt, d. H. Den OperandentypNullable<bool>
(auch @ geschriebbool?
), also habe ich es mit nicht dynamischer Eingabe 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, nahm aber an, dass die Implementierung des Visual C # -Compilers korrekt war, jetzt wusste ich es).
Jedoch wollte ich mit @ probierdynamic
bindung auch. Also habe ich es 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);
}
}
as überraschende Ergebnis ist, dass dies ohne Ausnahme läuf
Gut,x
undy
überrascht nicht, ihre Deklarationen führen dazu, dass beide Eigenschaften abgerufen werden, und die resultierenden Werte sind wie erwartet.x
isttrue
undy
istnull
.
Aber die Auswertung fürxx
vonA || B
führt zu keiner Ausnahme der Bindungszeit und nur zur EigenschaftA
wurde gelesen, nichtB
. Warum passiert das? Wie Sie sehen können, könnten wir das @ ändeB
getter, um ein verrücktes Objekt zurückzugeben, wie"Hello world"
, undxx
würde immer noch zu @ auswerttrue
ohne bindungsprobleme ...
EvaluatingA && B
(zumyy
) führt auch zu keinem Bindungsfehler. Und hier werden natürlich beide Eigenschaften abgerufen. Warum ist dies im Laufzeitbinder zulässig? Wenn das zurückgegebene Objekt vonB
wird in ein "schlechtes" Objekt geändert (wie einstring
) tritt eine verbindliche Ausnahme auf.
Ist das richtig? (Wie können Sie das aus der Spezifikation ableiten?)
Wenn du es versuchstB
als erster Operand, beideB || A
undB && A
Runtime-Binder-Ausnahme geben B | A
undB & A
gut funktionieren, da bei nicht kurzschließenden Betreibern alles normal ist|
und&
).
(Mit C # -Compiler von Visual Studio 2013 und Laufzeitversion .NET 4.5.2 ausprobiert.)