Ich habe einen Code, der wie folgt dargestellt werden kann:
public class ItemService {
public void DeleteItems(IEnumerable<Item> items)
{
// Save us from possible NullReferenceException below.
if(items == null)
return;
foreach(var item in items)
{
// For the purpose of this example, lets say I have to iterate over them.
// Go to database and delete them.
}
}
}
Jetzt frage ich mich, ob dies der richtige Ansatz ist oder ob ich eine Ausnahme machen soll. Ich kann Ausnahmen vermeiden, da das Zurückgeben dasselbe wäre, als würde eine leere Sammlung durchlaufen, was bedeutet, dass ohnehin kein wichtiger Code ausgeführt wird, aber auf der anderen Seite verstecke ich möglicherweise Probleme irgendwo im Code, denn warum sollte jemand anrufen wollen DeleteItems
mit null
Parameter? Dies kann darauf hindeuten, dass an einer anderen Stelle im Code ein Problem vorliegt.
Dies ist ein Problem, das ich normalerweise bei Methoden in Diensten habe, da die meisten von ihnen etwas tun und kein Ergebnis zurückgeben. Wenn also jemand ungültige Informationen übergibt, hat der Dienst nichts zu tun, sodass er zurückgibt.
quelle
Antworten:
Das sind zwei verschiedene Fragen.
Solltest du akzeptieren
null
? Das hängt von Ihrer allgemeinen Richtlinienull
in der Codebasis ab. Meiner Meinung nachnull
ist es eine sehr gute Praxis, überall zu verbieten , außer wo dies ausdrücklich dokumentiert ist, aber es ist noch besser, sich an die Konvention zu halten, die Ihre Codebasis bereits hat.Sollten Sie die leere Sammlung akzeptieren? Meiner Meinung nach: JA, absolut. Es ist viel mühsamer, alle Aufrufer auf nicht leere Sammlungen zu beschränken, als das mathematisch Richtige zu tun - auch wenn es einige Entwickler überrascht, die mit dem Konzept von Null nicht einverstanden sind.
quelle
AhaINoticedYouPassingInNullException
wenn die Laufzeit Ihnen bereits die Möglichkeit bietet,NullReferenceException
für Sie zu werfen , ohne dass Sie Code schreiben müssen. Es gibt einige Hilfsprogramme (z. B. Ihr Code-Coverage-Tool teilt Ihnen mit, ob Sie im ersten Fall einen Unit-Test für die Übergabe von Null durchgeführt haben, im zweiten Fall jedoch nicht), aber keine der Ausnahmen sollte bei jedem Aufruf des Dienstes ausprobiert / abgefangen werden. weil es normalerweise ein Programmiererfehler ist.NullReferenceException
oderAhaINoticedYouPassingInNullException
irgendwo anders auf hohem Niveau , Disaster-Recovery - Code. Und dieser Ausnahmehandler sollte wahrscheinlich einen Fehlerbericht erstellen :-)null
im Übrigen , wenn der Dienst, für den diese Methode aufgerufen wird, lautet : Enthalten die Steuerungen Boilerplate, um auch in diesem Fall zu erfassen und fortzufahren?ArgumentNullException
ist dem Ermöglichen des Auslösens eines internen Codes überlegen. Wenn SieNullReferenceException
lediglich die Ausnahmemeldung betrachten, ist es offensichtlich, dass es sich eher um einen Eingabefehler als um einen logischen Fehler im Methodenkörper an der Auslösestelle handelt Es ist wahrscheinlicher, dass Sie andere Daten in einem gültigen Zustand belassen haben, anstatt sie später teilweise von einer unerwarteten Null zu mutieren.Nullwert
Halten Sie sich, wie @KilianFoth bereits sagte, an Ihre allgemeinen Richtlinien. Wenn dies
null
als "Kurzform" für eine leere Liste behandelt werden soll, tun Sie dies auf diese Weise.Wenn Sie keine konsistente Richtlinie zu
null
Werten haben, empfehle ich die folgende:null
sollte reserviert werden, um Situationen darzustellen, die nicht durch den "normalen" Typ ausgedrückt werden können, z. B.null
"Ich weiß nicht". Und das ist eine gute Wahl, da jeder, der versucht, diesen Wert unachtsam zu verwenden, eine Ausnahme bekommt, was das Richtige ist.Die Verwendung
null
als Kurzform für eine leere Liste ist nicht so qualifiziert, da es bereits eine perfekte Darstellung gibt, da es sich um eine Liste mit null Elementen handelt. Und es ist eine technisch schlechte Wahl, da jeder Teil Ihres Codes, der sich mit Listen befasst, gezwungen ist, nach der gültigen Kurzschrift zu suchennull
.Leere Liste
Für eine
DeleteItems()
Methode bedeutet das Übergeben einer leeren Liste effektiv, nichts zu tun. Ich würde das als Argument zulassen, keine Ausnahme auslösen und einfach schnell zurückkehren.Natürlich könnte der Anrufer zuerst nach null Elementen suchen und den
DeleteItems()
Anruf in diesem Fall überspringen . Wenn es sich um eine Web-API handelt, sollte der Anrufer dies aus Effizienzgründen tun, um unnötigen Datenverkehr und Roundtrip-Latenzen zu vermeiden. Aber ich denke nicht, dass Ihre API das erzwingen sollte.quelle
Löst eine Ausnahme aus und behandelt Nullen im aufrufenden Code.
Versuchen Sie als Entwurfsregel, Null als Parameterwerte zu vermeiden. Es wird im Allgemeinen NullPointerExceptions reduzieren, da Nullen wirklich eine Ausnahme sein werden.
Schauen Sie sich außerdem den Rest Ihres Codes an. Wenn dies ein häufiges Muster in Ihrem Projekt ist, bleiben Sie konsistent.
quelle
Im Allgemeinen sollten Ausnahmen für Ausnahmesituationen reserviert werden, dh wenn der Code im aktuellen Kontext keine angemessene Vorgehensweise bietet.
Sie können diesen Denkprozess auf diese Situation anwenden. Da dies eine öffentliche Klasse mit einer öffentlichen Methode ist, verfügen Sie über eine öffentliche API und haben theoretisch keine Kontrolle darüber, was an sie übergeben wird.
Ihr Code hat keinen Kontext zu dem, was er nennt (wie es nicht sein sollte), und es gibt nichts, was Sie vernünftigerweise mit einem Nullwert tun können. Dies wäre sicherlich ein Kandidat für eine
ArgumentNullException
.quelle
null
.null
dir hast du keine Sammlung. Wenn der aufrufende Code eine Auflistung für die Methode liefern soll, stimmt etwas nicht, Sie sollten also werfen. Der einzige Grund, eine Null wie eine leere Auflistung zu behandeln, ist, wenn Sie vernünftigerweise erwarten können, dass der aufrufende Code Null-Auflistungen erzeugt. Wie in anderen Antworten bereits angemerkt, ist etwas meistensnull
eine Anomalie. Wenn Sie diese wie leere Auflistungen behandeln, ignorieren Sie möglicherweise ein Problem an einer anderen Stelle im Code.null
als leer bezeichnen, ist dies kontextspezifisch für diese Methode. An einer anderen Stelle in derselben Codebasis haben Sie möglicherweise einenIEnumerable
oderIContainer
-Parameter, der eine Art Filterung ausführt.null
Dies bedeutet möglicherweise "kein Filter" (alles zulassen), wohingegen ein leerer Filter bedeutet, dass nichts zulässig ist. Und an einer anderen Stellenull
könnte explizit "Ich weiß nicht" bedeuten. Danull
dies nicht immer überall dasselbe bedeutet, ist es eine gute Idee, überhaupt keine Bedeutung dafür zu erfinden, es sei denn, diese Bedeutung ist notwendig oder zumindest nützlich für jemanden.Bei dieser Frage scheint es sich nicht um Ausnahmen zu handeln, sondern um
null
ein gültiges Argument.In erster Linie müssen Sie also entscheiden, ob
null
das Argument dieser Methode ein zulässiger Wert für Sie ist. Wenn ja, brauchen Sie keine Ausnahme. Ist dies nicht der Fall, benötigen Sie eine Ausnahme.Ob Sie zulassen möchten
null
oder nicht, ist umstritten, wie viele Google-Hits zeigen. Das heißt, Sie erhalten keine eindeutige Antwort, und es liegt in gewisser Weise an der Meinung und Tradition des Ortes, an dem Sie arbeiten.Ein weiterer Streitpunkt ist, ob eine Bibliotheksfunktion in solchen Dingen wirklich streng oder so nachsichtig wie möglich sein sollte, solange sie nicht versucht, fehlerhafte Parameter zu "reparieren". Vergleichen Sie dies mit der Welt der Netzwerkprotokolle, der E-Mail-Übertragung usw. (die Schnittstellenverträge sind, genau wie Methoden in der Programmierung). In der Regel lautet die Richtlinie, dass der Absender das Protokoll so genau wie möglich einhält, während der Empfänger alles daran setzt, mit dem zu arbeiten, was gerade kommt.
Sie müssen sich also entscheiden: Ist es wirklich die Aufgabe einer Bibliotheksmethode, recht umfangreiche Richtlinien wie die
null
Handhabung durchzusetzen ? Insbesondere, wenn Ihre Bibliothek auch von anderen Personen verwendet wird (die möglicherweise andere Richtlinien haben).Ich würde mich wahrscheinlich auf der Seite irren,
null
Werte zuzulassen, ihre Semantik zu definieren und zu dokumentieren (dhnull = empty array
in diesem Fall) und keine Ausnahme auszulösen , es sei denn, 99% Ihres anderen ähnlichen Codes ("Bibliotheks" -Stil-Code) machen es anders 'runden.quelle
null
das Prinzip der Liberalität in dem, was Sie akzeptieren, schlucken wollen , dann wäre das Protokollieren oder sogar das Werfen hilfreich für Leute, deren Absicht es ist, streng in dem zu sein, was sie weitergeben, die aber sowohl ihren Code als auch ihren Code durcheinander gebracht haben ihre Unit-Tests in dem Maße, wie sienull
sowieso bestehen.null
, sondern es offen im Vertrag der Methode zu erklären, dass es akzeptabel ist (oder nicht, je nachdem, welche Lösung das OP anbietet), und dann die Frage, ob eine Ausnahme geworfen werden soll (oder nicht) löst sich von selbst.