Ich möchte die weitere Verarbeitung eines Objekts verhindern, wenn es null ist.
Im folgenden Code überprüfe ich, ob das Objekt entweder null ist:
if (!data.Equals(null))
und
if (data != null)
Ich erhalte jedoch eine NullReferenceException
at dataList.Add(data)
. Wenn das Objekt null war, hätte es niemals die if
Anweisung eingeben dürfen!
Daher frage ich, ob dies die richtige Methode ist, um zu überprüfen, ob ein Objekt null ist:
public List<Object> dataList;
public bool AddData(ref Object data)
bool success = false;
try
{
// I've also used "if (data != null)" which hasn't worked either
if (!data.Equals(null))
{
//NullReferenceException occurs here ...
dataList.Add(data);
success = doOtherStuff(data);
}
}
catch (Exception e)
{
throw new Exception(e.ToString());
}
return success;
}
Wenn dies die richtige Methode ist, um zu überprüfen, ob das Objekt null ist, was mache ich falsch (wie kann ich die weitere Verarbeitung des Objekts verhindern, um die NullReferenceException zu vermeiden)?
c#
null
nullreferenceexception
Entwickler
quelle
quelle
throw e;
versusthrow new Exception(e.ToString());
!= null
in Ihren Nullprüfungen verwenden..Equals
löst immer eine Ausnahme aus, wenn das Objekt null ist.throw e;
ist nicht viel besser.throw;
, auf der anderen Seite ...e.ToString()
eine Zeichenfolge, die nicht nur die Fehlermeldung, sondern auch die allerInnerExceptions
und die Stapelverfolgung enthält. Das ist also eine sehr fettreiche Ausnahmemeldung. Wenn Sie (zu Recht!) Diese Informationen aufbewahren und dort aufbewahren möchten, wo sie hingehören, verwenden Sie sie einfachthrow;
.Antworten:
Es ist nicht
data
das istnull
, aberdataList
.Sie müssen eine mit erstellen
Noch besser: Da es ein Feld ist, mach es
private
. Und wenn dich nichts daran hindert, mach es auchreadonly
. Nur gute Übung.Beiseite
Der richtige Weg, um auf Nichtigkeit zu prüfen, ist
if(data != null)
. Diese Art der Überprüfung ist für Referenztypen allgegenwärtig.Nullable<T>
überschreibt sogar den Gleichheitsoperator, um eine bequemere Ausdrucksweisenullable.HasValue
bei der Überprüfung auf Nichtigkeit zu bieten.Wenn Sie dies tun, erhalten
if(!data.Equals(null))
Sie einNullReferenceException
Wenndata == null
. Was irgendwie komisch ist, da die Vermeidung dieser Ausnahme in erster Linie das Ziel war.Sie machen das auch:
Das ist definitiv nicht gut. Ich kann mir vorstellen, dass Sie es dort ablegen, damit Sie in den Debugger einbrechen können, während Sie sich noch in der Methode befinden. In diesem Fall ignorieren Sie diesen Absatz. Andernfalls fangen Sie keine Ausnahmen umsonst. Und wenn Sie dies tun, werfen Sie sie mit just neu
throw;
.quelle
null != data
. Wenn Sie die Konstante an die erste Stelle setzen, wird der Tippfehler des Boneheadsnull = data
eher zu einem Compilerfehler als zu einer unbeabsichtigten Zuweisung. (Funktioniert auch für==
.)if (data = null)
ist bereits ein Fehler bei der Kompilierung aufgetreten. Selbst wenn es Jahrzehnte gedauert hat , müssen wir nicht mehr wirklich darauf achten. Selbst C ++ - Compiler geben leicht eine Warnung vor einer möglichen unbeabsichtigten Zuweisung für diesen Code aus.in C #> 7.0 verwenden
if (obj is null)
...Dadurch werden alle vom Objekt definierten == oder! = Ignoriert (es sei denn, Sie möchten sie natürlich verwenden ...).
Für nicht null verwenden
if (obj is object)
(oderif (!(obj is null))
)quelle
obj is not null
)if (obj aint null)
:(if (obj is object)
C # 6 hat eine monadische Nullprüfung :)
Vor:
nach dem:
quelle
result = myObject == null ? null : myObject.SomeProperty
und Ihr Beispiel gab mir einen Tipp zum Schreibenresult = myObject?.SomeProperty
. Mann!! Das ist hinterhältig. Ich liebe es immer noch zu programmieren ...Ihre Datenliste ist null, da sie nach dem von Ihnen veröffentlichten Code nicht instanziiert wurde.
Versuchen:
}}
quelle
[Bearbeitet, um den Hinweis von @ kelton52 wiederzugeben]
Der einfachste Weg ist zu tun
object.ReferenceEquals(null, data)
Da
(null==data)
ist NICHT garantiert zu arbeiten:Produziert:
quelle
Nein, du solltest verwenden
!=
. Wenndata
tatsächlich null ist, stürzt Ihr Programm nur mit einem ab,NullReferenceException
wenn versucht wird, dieEquals
Methode aufzurufennull
. Beachten Sie auch, dass Sie dieObject.ReferenceEquals
Methode verwenden sollten, wenn Sie speziell auf Referenzgleichheit prüfen möchten, da Sie nie wissen, wieEquals
sie implementiert wurde.Ihr Programm stürzt ab, weil
dataList
es null ist, da Sie es nie initialisieren.quelle
Das Problem in diesem Fall ist nicht, dass
data
es null ist. Es ist so, dassdataList
selbst null ist.An der Stelle, an der Sie deklarieren
dataList
, sollten Sie ein neuesList
Objekt erstellen und es der Variablen zuweisen.quelle
Zusätzlich zur Antwort von @Jose Ortega ist die Erweiterungsmethode besser geeignet
Und verwenden Sie die
IsNull
Methode für alle Objekte wie:quelle
return T == null ? true : false;
und nicht nurreturn T == null;
?Ab C # 8 können Sie das Eigenschaftsmuster 'leer' (mit Mustervergleich ) verwenden, um sicherzustellen, dass ein Objekt nicht null ist:
Dieser Ansatz bedeutet " wenn das Objekt auf eine Instanz von etwas verweist " (dh es ist nicht null).
Sie können sich das als das Gegenteil von vorstellen :
if (obj is null)...
. Dies gibt true zurück, wenn das Objekt nicht auf eine Instanz von etwas verweist.Weitere Informationen zu Mustern in C # 8.0 finden Sie hier .
quelle
Ab C # 9 können Sie tun
Für nicht null verwenden
Wenn Sie dieses Verhalten überschreiben müssen, verwenden Sie
==
und!=
entsprechend.quelle
Jeffrey L Whitledge hat recht. Ihr `dataList´-Objekt selbst ist null.
Es gibt noch ein weiteres Problem mit Ihrem Code: Sie verwenden das Schlüsselwort ref, was bedeutet, dass die Argumentdaten nicht null sein dürfen! Die MSDN sagt:
Es ist auch keine gute Idee, Generika mit dem Typ "Objekt" zu verwenden. Generika sollten das Ein- und Auspacken vermeiden und auch die Typensicherheit gewährleisten. Wenn Sie einen gemeinsamen Typ möchten, machen Sie Ihre Methode generisch. Schließlich sollte Ihr Code so aussehen:
quelle
Wie andere haben bereits darauf hingewiesen, ist es nicht ,
data
sondern wahrscheinlichdataList
das istnull
. Darüber hinaus...catch
-throw
ist ein Antimuster, das mich fast immer dazu bringt, mich jedes Mal zu übergeben, wenn ich es sehe. Stellen Sie sich vor, dass etwas in etwas, dasdoOtherStuff()
anruft, schief geht . Alles , was Sie zurück erhalten , ist einException
Objekt, bei dem geworfenthrow
inAddData()
. Keine Stapelverfolgung, keine Aufrufinformationen, kein Status, überhaupt nichts, was auf die wahre Ursache des Problems hinweist, es sei denn, Sie gehen hinein und schalten Ihren Debugger so, dass eine ausgelöste Ausnahme unterbrochen wird, anstatt eine Ausnahme nicht zu behandeln. Wenn Sie eine Ausnahme abfangen und sie auf irgendeine Weise erneut auslösen , insbesondere wenn der Code im try-Block in irgendeiner Weise nicht trivial ist, tun Sie sich selbst (und Ihren Kollegen, Gegenwart und Zukunft) einen Gefallen und werfen Sie den gesamtentry
-catch
Block aus . Gewährt,throw;
ist besser als die Alternativen, aber Sie geben sich selbst (oder wer auch immer versucht, einen Fehler im Code zu beheben) völlig unnötige Kopfschmerzen. Dies bedeutet nicht, dass Try-Catch-Throw per se notwendigerweise böse ist, solange Sie mit dem Ausnahmeobjekt, das in den Catch-Block geworfen wurde, etwas Relevantes tun .Dann gibt es die potenziellen Probleme, überhaupt zu fangen
Exception
, aber das ist eine andere Sache, zumal Sie in diesem speziellen Fall eine Ausnahme auslösen.Eine andere Sache, die mir mehr als gefährlich erscheint, ist, dass
data
sich der Wert während der Ausführung der Funktion möglicherweise ändern kann, da Sie als Referenz übergeben werden. Die Nullprüfung wird möglicherweise bestanden, aber bevor der Code etwas mit dem Wert anfangen kann, wird er geändert - vielleicht innull
. Ich bin mir nicht sicher, ob dies ein Problem ist oder nicht (es könnte nicht sein), aber es scheint sich zu lohnen, darauf zu achten.quelle
verwenden:
Bedingte Verwendung:
Update (auf andere Weise) aktualisiert am 31.08.2017. Danke für den Kommentar.
quelle
cond ? true : false;
ist völlig gleichbedeutend mit nurcond
. Dies fügt nichts hinzu.return T == null;
auch einen booleschen Wert zurück!return T == null ? true : false;
nur zu benutzenreturn T == null;
.Wenn Sie Objekte der Klasse erstellen, müssen Sie mithilfe des folgenden Codes überprüfen, ob das Objekt null ist oder nicht.
Beispiel: Objekt1 ist Objekt der Klasse
quelle
Ich habe gerade eine Methode befolgt, die wir normalerweise in Java-Skripten anwenden würden. Um ein Objekt in eine Zeichenfolge zu konvertieren und dann zu überprüfen, ob sie null sind.
quelle
Ich habe es einfacher gemacht (positiver Weg) und es scheint gut zu funktionieren.
Da jede Art von "Objekt" zumindest ein Objekt ist
quelle