Da die Sprachspezifikation dort einen Ausdruck vom Typ erwartet System.Exception
(daher null
in diesem Kontext gültig ist) und diesen Ausdruck nicht auf Nicht-Null beschränkt. Im Allgemeinen kann nicht festgestellt werden, ob der Wert dieses Ausdrucks ist null
oder nicht. Es müsste das Halteproblem lösen. Die Laufzeit muss sich null
sowieso mit dem Fall befassen . Sehen:
Exception ex = null;
if (conditionThatDependsOnSomeInput)
ex = new Exception();
throw ex;
Sie könnten natürlich den speziellen Fall, das null
Literal ungültig zu machen, ungültig machen, aber das würde nicht viel helfen. Warum also Spezifikationsraum verschwenden und die Konsistenz für wenig Nutzen reduzieren?
Haftungsausschluss (bevor ich von Eric Lippert geschlagen werde): Dies ist meine eigene Spekulation über die Gründe für diese Designentscheidung. Natürlich war ich nicht im Designtreffen;)
Die Antwort auf Ihre zweite Frage, ob eine in einer catch-Klausel abgefangene Ausdrucksvariable jemals null sein kann: Während die C # -Spezifikation null
keine Aussage darüber enthält, ob andere Sprachen die Weitergabe einer Ausnahme verursachen können , definiert sie die Art und Weise, wie Ausnahmen weitergegeben werden:
Die etwaigen catch-Klauseln werden in der Reihenfolge ihres Auftretens geprüft, um einen geeigneten Handler für die Ausnahme zu finden. Die erste catch-Klausel , die den Ausnahmetyp oder einen Basistyp des Ausnahmetyps angibt, wird als Übereinstimmung betrachtet. Eine allgemeine catch-Klausel gilt als Übereinstimmung für jeden Ausnahmetyp. [...]
Denn null
die fette Aussage ist falsch. Obwohl dies nur auf den Aussagen der C # -Spezifikation basiert, können wir nicht sagen, dass die zugrunde liegende Laufzeit niemals null auslösen wird. Wir können jedoch sicher sein, dass selbst wenn dies der Fall ist, dies nur von der generischen catch {}
Klausel behandelt wird.
Für C # -Implementierungen auf der CLI können wir auf die ECMA 335-Spezifikation verweisen. In diesem Dokument werden alle Ausnahmen definiert, die die CLI intern auslöst (keine davon null
), und es wird erwähnt, dass benutzerdefinierte Ausnahmeobjekte von der throw
Anweisung ausgelöst werden . Die Beschreibung für diese Anweisung ist praktisch identisch mit der C # throw
-Anweisung (außer dass sie den Typ des Objekts nicht auf Folgendes beschränkt System.Exception
):
Beschreibung:
Die throw
Anweisung wirft das Ausnahmeobjekt (Typ O
) auf den Stapel und leert den Stapel. Einzelheiten zum Ausnahmemechanismus finden Sie unter Partition I.
[Hinweis: Während die CLI das Auslösen von Objekten zulässt, beschreibt die CLS eine bestimmte Ausnahmeklasse, die für die Sprachinteroperabilität verwendet werden soll. Endnote]
Ausnahmen:
System.NullReferenceException
wird geworfen wenn obj
ist null
.
Richtigkeit:
Durch die korrekte CIL wird sichergestellt, dass das Objekt immer entweder null
oder eine Objektreferenz (dh vom Typ O
) ist.
Ich glaube, diese reichen aus, um zu dem Schluss zu kommen, dass es keine Ausnahmen gibt null
.