2011-01-17 5 views
0

ich auf null wissen, dass, wenn ein NullReferenceException geworfen wird, wird die Fehlermeldung besagt:Mögliche Gründe für „Nullreferenceexception“ neben einen Objektverweis dereferencing gesetzt

Objektverweis auf eine Instanz eines Objekts nicht festgelegt.

Und ich weiß, diese Nachricht wird ausgelöst, wenn ich versuche, eine null Objektreferenz zu dereferenzieren.

Die Fehlermeldung bedeutet, dass es einen Grund für eine NullReferenceException neben einer Objektreferenz gibt, die null ist (vielleicht eine schlechte Speicheradresse oder etwas ähnliches). Ist das der Fall?


Edit: Ich bin mehr mit den Gründen eine NullReferenceException als der Wortlaut der Fehlermeldung ausgelöst werden könnte. Der Wortlaut der Fehlermeldung ist genau das, was die Frage ausgelöst hat.

+0

Sie können diese Frage neu formulieren, um sich auf mögliche Ursachen von NREs zu konzentrieren, "da eine Objektreferenz null ist", weil der Grund für die genaue Formulierung der Fehlermeldung nicht objektiv beantwortet werden kann (außer vom .NET-Designteam, vielleicht: P), und diese Frage wird wahrscheinlich als zu subjektiv geschlossen werden. –

+2

Subjektiv und argumentativ? "Ja wirklich?" –

+0

@djacobson: Aktualisierte den Titel der Frage. –

Antwort

5

Ich vermute, es versucht, sprachneutral zu sein. Ein Visual Basic-Programmierer wird beispielsweise zu "nichts" statt "null" verwendet. Offensichtlich ist der Typenname nicht sprachneutral, aber zumindest wenn die Nachricht ist, das ist ein Anfang.

Ich weiß nicht, dass Sie das bekommen würden, wenn Sie irgendwie versucht haben, eine "schlechte" Speicheradresse zu dereferenzieren ... an diesem Punkt gibt es einen weitaus schlimmeren CLR-Fehler.

Eine andere Möglichkeit ist, dass versucht wird, zu vermeiden, dass Sie den Wert des Verweises explizit auf null gesetzt haben - es könnte beispielsweise nur der Standardwert einer Referenztypvariablen sein.

+4

'" Ich weiß nicht, dass du das bekommen würdest, wenn du irgendwie versucht hast, eine "schlechte" Speicheradresse zu dereferenzieren "... Das macht eigentlich Spaß. Dereferenzieren eines Zeigers mit der Adresse <65536 löst eine "NullReferenceException" aus, und darüber wird entweder eine "AccessViolationException" ausgelöst oder ausgelöst. Die Adressen <65536 sind in Windows reserviert, zusammen mit den oberen 65536 Adressen. http://msdn.microsoft.com/en-us/library/ms810627.aspx – porges

+0

@Porges: So könnte diese Ausnahme auftreten, wenn eine ungültige Zeigeradresse dereferenziert? Wie würdest du das überhaupt machen? –

+0

'int g = * ((int *) 12345);' - muss in einem 'unsicheren' Kontext sein – porges

1

Wenn ein Objekt, wie so deklariert ist:

MyClass MyObject; 

es als eine Objektreferenz definiert ist. Da es jedoch null ist (und nicht instanziiert wurde), wird es nicht auf eine Instanz eines Objekts festgelegt. Wenn wir hinzufügen:

MyObject = new MyClass(); 

dann wurde der Verweis auf eine neue Instanz des Objekts festgelegt.

Wenn wir setzen es später auf null:

MyObject = null; 

Dann ist es wieder in den Nullzustand. Daher deckt die Ausnahmebedingungsnachricht beide Fälle ab (nicht instanziiert oder explizit auf null gesetzt).

2

Wenn Sie sagen, dass die Referenz auf null gesetzt ist, sagt das nicht viel darüber aus, was zu tun ist. In ihrem Versuch, "hilfreicher" zu sein, sagen sie Ihnen, was passieren muss: Die Objektreferenz muss auf eine Instanz eines Objekts gesetzt werden.

Ich lese das nicht wirklich so, als deutete darauf hin, dass es neben einer Referenz auch andere Gründe geben könnte, die null sind. Wenn es nicht initialisiert wurde, verursacht es einen Kompilierungsfehler. Die Quintessenz ist, dass die Referenz zu dem Zeitpunkt, an dem Sie sie verwenden wollten, sich nicht auf etwas bezieht.

0

Es ist Teil der Common Language Specification. Sehen Sie sich den Unterschied zwischen einer statischen Methode und einer Instanzmethode an.

Eine statische Methode gehört zum Typ und benötigt daher keine Instanz. Wenn Sie den IL-Byte-Code betrachten, werden statische Methoden als "Aufruf" bezeichnet.

Eine nicht statische Methode ist jedoch definitionsgemäß eine Instanzmethode und erfordert eine Instanz. Der IL-Befehl lautet "callvirt". Der Hauptunterschied zwischen "call" und "callvirt" besteht darin, dass "callvirt" prüft, ob das Ziel, für das die Methode aufgerufen werden soll, nicht null ist.

+0

Sie müssen * Call * nicht verwenden, um eine Instanzmethode aufzurufen. Sie können call verwenden, und tatsächlich kann "this" in einer Instanzmethode null sein, wenn es auf diese Weise aufgerufen wird. Der C# -Compiler ruft (fast) immer Instanzmethoden mit callvirt auf, aber ich glaube, dass es völlig legal ist, stattdessen IL zu verwenden. –

+0

Ich nehme an, Sie können IL über emit generieren, aber ich denke nicht, dass das Markieren von etwas als "sealed" oder "internal" verhindern wird, dass der Compiler keine callvirt-Anweisungen generiert, nein? Wenn nicht, zitieren Sie. – bryanbcook

Verwandte Themen