Ich würde erwarten, dass der Compiler versucht, x als int zu interpretieren, aber anscheinend nicht.
Bearbeiten nach 280Z28: NullReferenceException
wurde in InvalidOperationException
geändert, was Nullable<T>.Value
löst aus, wenn HasValue
falsch ist.
Dies entspricht der Spezifikation für aufgehobene binäre Operatoren. Aus §7.2.7:
Für die binären Operatoren
+ - * / % & | ^ << >>
Eine aufgehobene Form eines Operators existiert, wenn der Operand und die Ergebnistypen alle nicht nullbaren Werttypen sind. Die aufgehobene Form wird konstruiert, indem jedem Operanden und Ergebnistyp ein einzelner
?
-Modifikator hinzugefügt wird. Der aufgehobene Operator erzeugt einen Nullwert, wenn einer oder beide Operanden null sind (eine Ausnahme sind die Operatoren & amp; und | des bool? -Typs, wie in §7.10.3 beschrieben). Andernfalls entpackt der gehobene Operator die Operanden, wendet den zugrunde liegenden Operator an und umschließt das Ergebnis.
Der Grund dafür ist folgender: Sie müssen an null
für einen Nullwert-Typ denken, der bedeutet "Ich weiß nicht, was der Wert ist". Was ist das Ergebnis von "Ich weiß nicht" plus eins? "Ich weiß es nicht." Daher sollte das Ergebnis null
sein.
Warum sollten Sie erwarten, dass der Compiler es als int darstellt, wenn Sie es als Nullable deklariert haben? Der Compiler tut, was Sie ihm gesagt haben, und null +1 = null.
Sie müssen explizit casten oder x.HasValue überprüfen, bevor Sie versuchen, einen int. hinzuzufügen.
Der Grund dafür ist, dass der Compiler einen 'aufgehobenen' Operator für Nullable-Typen erstellt - in diesem Fall ist es etwa so:
%Vor%Ich denke, wenn Sie versuchen, das Ergebnis einem nicht nullbaren Wert zuzuweisen, wird der Compiler gezwungen, die nicht nullbare Überladung zu verwenden und x zu einem int zu konvertieren.
%Vor%Leider nicht. Das X in x = X + 1 ist null wie in der ersten Zeile, also addieren Sie 1 zu null, was gleich null ist.
Da es ein nullwertfähiges int ist, können Sie x.HasValue verwenden, um zu überprüfen, ob es einen Wert hat, und dann x.Value, um den tatsächlichen int-Wert herauszulösen
Unabhängig davon, ob x
tatsächlich nie null ist, das ist nicht einmal der Punkt.
Der Punkt ist, wann haben Sie jemals eine NullReferenceException
gesehen, wenn Sie versuchen, eine Addition durchzuführen?
Das folgende Beispiel wirft auch keine NullReferenceException
und ist absolut gültig.
Sie würden nur NullReferenceException
erhalten, wenn Sie versuchen, auf ein Mitglied eines Objekts zuzugreifen, das null ist.
int? kann niemals null sein, weil es eine Struktur ist. Strukte leben auf dem Stapel und der Stapel behandelt NULL nicht gut.
Siehe Was ist eine NullPointerException und wie behebe ich sie?
Außerdem haben die Nullable-Typen 2 sehr nützliche Eigenschaften: HasValue, Value
Dieser Code:
%Vor%Sollte umgestaltet werden:
%Vor%