Erwartetes Verhalten, wenn eine Anforderung für eine Sammlung keine Elemente enthält


13

Angenommen, Ihnen wird Folgendes gegeben ...

List<Thing> theThings = fubar.Things.All();

Wenn nichts zurückzukehren wäre, was würden Sie von fubar.Things.All () erwarten?

Edit: Danke für die Meinungen. Ich werde ein bisschen warten und den Eintrag mit den meisten Ups annehmen.

Ich bin mit den bisherigen Antworten einverstanden, insbesondere mit denen, die eine leere Sammlung vorschlagen. Ein Anbieter hat eine API mit mehreren Aufrufen bereitgestellt, die dem obigen Beispiel ähneln. Ein Anbieter, der im vergangenen Jahr mit seinen APIs einen Umsatz von 4,6 Millionen US-Dollar erzielt hat. Sie tun etwas, mit dem ich grundsätzlich nicht einverstanden bin - sie werfen eine Ausnahme.


Scheint ein ziemlich solider Konsens zu sein [hier] [1]: Leere Sammlung. Immer. [1]: stackoverflow.com/questions/1969993/…
Jesse C. Slicer

Wofür ist der Datentyp Things? Wenn es sinnvoll ist, das ThingsFeld null zurückgeben zu lassen, ist es sinnvoll, dass Sie eine Ausnahme erhalten, da Sie vor Ihrem Aufruf von nicht auf null geprüft haben All(). Ich stimme jedoch den Leuten zu, die denken, dass fubar.Thingseine leere Sammlung anstelle von null zurückgegeben werden sollte.
Colin D

Ich verstehe, worauf du hinaus willst, Colin. In diesem Fall können Sie davon ausgehen, dass Things vorhanden ist und All () statisch ist. Die Ausnahme ist spezifisch dafür, dass die Sammlung leer ist, nicht aus irgendeinem anderen Grund.
Abscode

OMG sie werfen eine Ausnahme ...! o_O
Stuart Marks

Die interessantere Frage wäre nun, welchen Grund auf der Erde jemand haben könnte, in solch einen generischen Fall zu werfen, oder was macht den Fall so besonders, um das Werfen zu rechtfertigen?
Martin Ba

Antworten:


29

Von den beiden Möglichkeiten (dh Rückgabe nulleiner leeren Sammlung oder Rückgabe einer leeren Sammlung) würde ich die Rückgabe einer leeren Sammlung wählen, da der Aufrufer eine Überprüfung des zurückgegebenen Werts überspringen kann. Anstatt dies zu schreiben

List<Thing> theThings = fubar.Things.All();
if (theThings != null) {
    for (Thing t : theThings) {
        t.doSomething();
    }
}

Sie könnten folgendes schreiben:

List<Thing> theThings = fubar.Things.All();
for (Thing t : theThings) {
    t.doSomething();
}

Dieses zweite Codefragment ist kürzer und einfacher zu lesen, da die Verschachtelungsebene um eins niedriger ist.


2
Ich denke, ich finde es auch einfacher, begrifflich zu verstehen, wie "das Set ist leer" (keine Elemente). Null ist 'es gibt keine Menge', was ganz anders ist. (Dies sollte auch Dinge abdecken, die logische Unmöglichkeiten sind - die Menge aller ungeraden, die auch gerade sind, sollte leer sein, nicht null). Ich bin mir ehrlich gesagt nicht sicher, was (logischerweise) eine Nullmenge darstellen würde ... (selbst wenn Sie auf einer Insel nackt sind, sind Ihre Besitztümer eine leere Menge, keine Nullmenge)
Clockwork-Muse

@ X-Zero Aber wenn du dich nackt ausbeutest, könnten "Habseligkeiten im Rucksack" einen Nullsatz zurückgeben, da du nicht einmal einen Rucksack bei dir hast. Es könnte eine BackpackNotFoundException sein, aber nur, wenn es wirklich unerwartet ist. Es sollte ein normaler Zustand sein, zum Beispiel in einem Inselüberlebensspiel.
Izkata,

Der zusätzliche Null-Check hilft mir, nachts zu schlafen.
Joel B

6

Ich würde eine leere Liste erwarten. theThingswäre immer noch ein Objekt, aber theThings.Countoder theThings.size()würde zurückkehren 0.


5

Derartige Designprobleme werden durch das Null-Objektmuster behoben

... Anstatt eine Nullreferenz zu verwenden, um die Abwesenheit eines Objekts (z. B. eines nicht vorhandenen Kunden) anzuzeigen, wird ein Objekt verwendet, das die erwartete Schnittstelle implementiert, dessen Methodentext jedoch leer ist. Der Vorteil dieses Ansatzes gegenüber einer funktionierenden Standardimplementierung besteht darin, dass ein Nullobjekt sehr vorhersehbar ist und keine Nebenwirkungen hat: Es führt nichts aus.

Beispielsweise kann eine Funktion eine Liste von Dateien in einem Verzeichnis abrufen und für jede eine Aktion ausführen. Im Fall eines leeren Verzeichnisses kann eine Antwort darin bestehen, eine Ausnahme auszulösen oder eine Nullreferenz anstelle einer Liste zurückzugeben. Daher muss der Code, der eine Liste erwartet, überprüfen, ob tatsächlich eine vorhanden ist, bevor er fortfährt, was das Design verkomplizieren kann ...

In Ihrem Fall besonders zutreffender Vorschlag (Rückgabe, Listwenn keine Things vorhanden sind ):

... Wenn Sie stattdessen ein Nullobjekt (dh eine leere Liste ) zurückgeben, müssen Sie nicht überprüfen, ob der Rückgabewert tatsächlich eine Liste ist. Die aufrufende Funktion durchläuft die Liste möglicherweise einfach wie gewohnt und führt so praktisch nichts aus. Es ist jedoch weiterhin möglich zu überprüfen, ob der Rückgabewert ein Null-Objekt ist (z. B. eine leere Liste) und auf Wunsch anders zu reagieren.


3

Sie sollten meiner Meinung nach einen leeren Wert zurückgeben. Ich kenne C # nicht, aber in Java haben wir Folgendes:

  List list = Collections.EMPTY_LIST;
  Set set = Collections.EMPTY_SET;
  Map map = Collections.EMPTY_MAP;

  // For the type-safe 
  List<String> s = Collections.emptyList();
  Set<Long> l = Collections.emptySet();
  Map<Date> d = Collections.emptyMap();

http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html


1
Das C # -Äquivalent ist Enumerable.Empty<T>(), das eine leere zurückgibt IEnumerable<T>(siehe msdn.microsoft.com/en-us/library/bb341042.aspx )
Avner Shahar-Kashtan

1
Aktuelle Dokumente finden Sie hier: docs.oracle.com/javase/7/docs/api/java/util/Collections.html - Die 1.4.2-Dokumente sind jetzt ungefähr zehn Jahre alt.
Stuart Marks

2

Ich würde eine leere Auflistung über die Rückgabe eines Nullwerts zurückgeben, da Sie auf diese Weise vermeiden können, eine Nullüberprüfung in den aufrufenden Code zu schreiben.


2

Die beiden Lösungen bedeuten unterschiedliche Dinge.

Wenn es nur null von der Sache gibt, die Sie zurückgeben, geben Sie IMMER eine leere Sammlung zurück! Nehmen Sie den Fall einer Verzeichnisliste. Wenn das Verzeichnis keine Dateien enthält, wird eine leere Dateisammlung zurückgegeben.

Wenn das Verzeichnis jedoch nicht vorhanden ist, ist dies nicht wirklich angemessen. "Ich kann nichts zurückgeben" bedeutet etwas völlig anderes. In diesem Fall sollten Sie entweder null zurückgeben oder eine Ausnahme auslösen. Geben Sie nicht einfach eine leere Auflistung zurück, als wäre nichts falsch.


Sehr vernünftige Erklärung. Das zurückgegebene Ergebnis sollte den ungültigen Status nicht abdecken, wir haben Ausnahmen dafür.
Ivaylo Slavov
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.