Zu dieser nicht behandelten .NET-Ausnahmemeldung:
Der Objektverweis wurde nicht auf eine Instanz eines Objekts festgelegt.
Warum zeigt .NET nicht an, welches Objekt es ist null
?
Ich weiß, dass ich null
den Fehler suchen und beheben kann. Warum hilft .NET jedoch nicht dabei, darauf hinzuweisen, welches Objekt eine Nullreferenz hat und welcher Ausdruck die ausgelöst hat NullReferenceException
?
Antworten:
(Informationen zum neuen Ausnahme-Helfer in Visual Studio 2017 finden Sie am Ende dieser Antwort.)
Betrachten Sie diesen Code:
Dies wirft ein
NullReferenceException
in die zweite Zeile und Sie möchten wissen, warum .NET Ihnen nicht sagt, dass ess
null war, als die Ausnahme ausgelöst wurde.Um zu verstehen, warum Sie diese Informationen nicht erhalten, sollten Sie sich daran erinnern, dass nicht die C # -Quelle ausgeführt wird, sondern IL:
Es ist der
callvirt
Opcode, der das auslöst,NullReferenceException
und das tut es, wenn das erste Argument auf dem Auswertungsstapel eine Nullreferenz ist (die, die mit geladen wurdeldloc.0
).Wenn .NET erkennen soll, dass es sich
s
um eine Nullreferenz handelt, sollte es in gewisser Weise nachverfolgen, dass das erste Argument auf dem Evaluierungsstapel aus einer Form stammts
. In diesem Fall ist es für uns leicht zu erkennen,s
dass es null war, aber was ist, wenn der Wert ein Rückgabewert eines anderen Funktionsaufrufs war und nicht in einer Variablen gespeichert wurde? Auf jeden Fall ist diese Art von Informationen nicht das, was Sie in einer virtuellen Maschine wie der virtuellen .NET-Maschine verfolgen möchten.Um dieses Problem zu vermeiden, schlage ich vor, dass Sie in allen öffentlichen Methodenaufrufen eine Argument-Null-Prüfung durchführen (es sei denn, Sie erlauben natürlich die Null-Referenz):
Wenn null an die Methode übergeben wird, erhalten Sie eine Ausnahme, die genau beschreibt, wo das Problem liegt (
s
dh null).Vier Jahre später hat Visual Studio 2017 jetzt einen neuen Ausnahme-Helfer, der versucht zu erkennen, was null ist, wenn a
NullReferenceException
ausgelöst wird. Es kann Ihnen sogar die erforderlichen Informationen geben, wenn es sich um den Rückgabewert einer Methode handelt, die null ist:Beachten Sie, dass dies nur in einem DEBUG-Build funktioniert.
quelle
null
.null
Beachten Sie, dass das OP nicht behauptet, dass er oder sie wissen möchte, dass Debug-Builds auch für Release-Builds ausreichend sein können.null
), mit der Zeile und Spalte der Quelldatei zu korrelieren, die diese Objektreferenz zurückgegeben hat.Wie soll die Fehlermeldung im folgenden Fall aussehen?
Hier gibt es keine Variablennamen zu melden!
quelle
Object reference obtained from AnyObject.GetANullObject() not set to an instance of an object.
eine Fehlermeldung erwarten .Nun, das müssen die Ingenieure von Microsoft beantworten. Aber Sie können natürlich einen Debugger verwenden und watch hinzufügen, um herauszufinden, welche davon ein Problem haben.
Die Ausnahme ist jedoch
NullReferenceException
, dass die Referenz nicht vorhanden ist . Sie können das Objekt nicht erhalten, das überhaupt nicht erstellt wurde.but why .NET don't tell us which object is null?
Weil es nicht weiß, welches Objekt null ist. Das Objekt existiert einfach nicht!Gleiches gilt, wenn ich sage, dass C # zu .NET IL-Code kompiliert wurde. Der .NET IL-Code kennt die Namen oder Ausdrücke nicht. Es kennt nur Referenzen und deren Standort. Auch hier kann man nicht bekommen, was nicht existiert. Der Ausdruck oder der Variablenname existiert nicht.
Philosophie: Sie können kein Omelett machen, wenn Sie überhaupt kein Ei haben.
quelle
Nicht sicher, aber dies kann daran liegen, dass .Net nicht weiß, ob es sich um eine vordefinierte Klasse oder eine benutzerdefinierte Klasse handelt. Wenn es vordefiniert ist, kann es null sein (wie eine Zeichenfolge, die 2 Bytes belegt), aber wenn es benutzerdefiniert ist, müssen wir eine Instanz davon erstellen, damit es weiß, dass dieses Objekt so viel Speicher belegt. Daher wird zur Laufzeit ein Fehler ausgegeben.
quelle
Gute Frage. Das Meldungsfeld ist nur knapp nutzlos. Selbst wenn es eine Meile tief von der Referenzdefinition entfernt ist, wären einige Klassen, Baugruppen, Dateien oder andere Informationen besser als das, was sie derzeit bereitstellen (sprich: besser als nichts).
Am besten führen Sie es im Debugger mit Debugging-Informationen aus, und Ihre IDE wird an der betreffenden Zeile unterbrochen (was ziemlich deutlich zeigt, dass nützliche Informationen tatsächlich verfügbar sind).
quelle