Ich habe einige Nachforschungen angestellt, indem ich verschiedene Methoden verwendet habe, um einem nullbaren int Werte zuzuweisen. Folgendes ist passiert, als ich verschiedene Dinge getan habe. Sollte klären, was los ist. Denken Sie daran: Nullable<something>
oder die Kurzschrift something?
ist eine Struktur, für die der Compiler anscheinend viel Arbeit leistet, damit wir sie mit null verwenden können, als wäre es eine Klasse.
Wie Sie unten sehen werden, SomeNullable == null
und SomeNullable.HasValue
wird immer wieder zurückkehren ein wahr oder falsch erwartet. Obwohl unten nicht gezeigt, SomeNullable == 3
ist es auch gültig (vorausgesetzt, SomeNullable ist ein int?
).
Während SomeNullable.Value
uns einen Laufzeitfehler bekommt , wenn wir zugewiesen null
zu SomeNullable
. Dies ist in der Tat der einzige Fall, in dem Nullables dank einer Kombination überladener Operatoren, die überladen sind, ein Problem verursachen könnenobject.Equals(obj)
Methode und Compiler-Optimierung und Affengeschäft.
Hier ist eine Beschreibung von Code, den ich ausgeführt habe, und welche Ausgabe er in Labels erzeugt hat:
int? val = null;
lbl_Val.Text = val.ToString(); //Produced an empty string.
lbl_ValVal.Text = val.Value.ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValEqNull.Text = (val == null).ToString(); //Produced "True" (without the quotes)
lbl_ValNEqNull.Text = (val != null).ToString(); //Produced "False"
lbl_ValHasVal.Text = val.HasValue.ToString(); //Produced "False"
lbl_NValHasVal.Text = (!(val.HasValue)).ToString(); //Produced "True"
lbl_ValValEqNull.Text = (val.Value == null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValValNEqNull.Text = (val.Value != null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")
Ok, versuchen wir die nächste Initialisierungsmethode:
int? val = new int?();
lbl_Val.Text = val.ToString(); //Produced an empty string.
lbl_ValVal.Text = val.Value.ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValEqNull.Text = (val == null).ToString(); //Produced "True" (without the quotes)
lbl_ValNEqNull.Text = (val != null).ToString(); //Produced "False"
lbl_ValHasVal.Text = val.HasValue.ToString(); //Produced "False"
lbl_NValHasVal.Text = (!(val.HasValue)).ToString(); //Produced "True"
lbl_ValValEqNull.Text = (val.Value == null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValValNEqNull.Text = (val.Value != null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")
Trotzdem wie zuvor. int? val = new int?(null);
Beachten Sie, dass das Initialisieren mit , wobei null an den Konstruktor übergeben wurde, einen COMPILE-Zeitfehler erzeugt hätte, da der Wert des nullbaren Objekts NICHT nullwertfähig ist. Nur das Wrapper-Objekt selbst kann gleich null sein.
Ebenso würden wir einen Kompilierungszeitfehler erhalten von:
int? val = new int?();
val.Value = null;
ganz zu schweigen davon, dass dies val.Value
sowieso eine schreibgeschützte Eigenschaft ist, was bedeutet, dass wir nicht einmal so etwas verwenden können wie:
val.Value = 3;
Aber auch hier können wir mit polymorphen überladenen impliziten Konvertierungsoperatoren Folgendes tun:
val = 3;
Sie müssen sich keine Sorgen um Polysomthing machen, was auch immer funktioniert, solange es richtig funktioniert? :) :)