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 @ probierdynamicbindung 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.)

Antworten auf die Frage(6)

Ihre Antwort auf die Frage