Comportamento previsto quando una richiesta per una raccolta avrà zero elementi


13

Diciamo che ti viene dato il seguente ...

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

Se non ci fosse nulla da restituire, cosa ti aspetteresti da restituire fubar.Things.All ()?

Modifica: grazie per le opinioni. Aspetterò un po 'e accetterò l'ingresso con il maggior numero di up.

Sono d'accordo con le risposte finora, in particolare quelle che suggeriscono una raccolta vuota. Un fornitore ha fornito a un'API diverse chiamate simili all'esempio precedente. Un fornitore che ha realizzato entrate per $ 4,6 milioni l'anno scorso tramite le loro API, BTW. Fanno qualcosa che fondamentalmente non sono d'accordo - lanciano un'eccezione.


Sembra essere un consenso piuttosto solido [qui] [1]: raccolta vuota. Sempre. [1]: stackoverflow.com/questions/1969993/…
Jesse C. Slicer,

A cosa serve il tipo di dati Things? Se ha senso che il Thingscampo ritorni a null, allora ha senso ricevere un'eccezione perché non hai verificato la presenza di null prima della chiamata a All(). Tuttavia, sono d'accordo con le persone che pensano che fubar.Thingsdovrebbe restituire una raccolta vuota anziché nulla.
Colin D,

Vedo a cosa stai arrivando, Colin. In questo caso, puoi presumere che le cose esistano e All () sia statico. L'eccezione è specifica per la raccolta vuota, non per qualche altro motivo.
abscode

OMG lanciano un'eccezione ...! o_O
Stuart segna il

Ora, la domanda più interessante sarebbe quale motivo sulla terra qualcuno avrebbe potuto lanciare in un caso così generico, o cosa rende il caso così speciale da giustificare il lancio ??!
Martin Ba,

Risposte:


29

Delle due possibilità (cioè restituire una nullo restituire una raccolta vuota) sceglierei di restituire una raccolta vuota, perché consente al chiamante di saltare un controllo del valore restituito. Invece di scrivere questo

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

sarebbero in grado di scrivere questo:

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

Questo secondo frammento di codice è più breve e più facile da leggere, poiché il livello di annidamento è inferiore di uno.


2
Penso che troverei anche più facile capire concettualmente come "il set è vuoto" (nessun oggetto). Null è "non esiste un set", il che è abbastanza diverso. (Questo dovrebbe coprire anche le cose che sono impossibilità logiche - l'insieme di tutti gli elementi che sono anche dispari dovrebbero essere vuoti, non nulli). Onestamente non sono sicuro di cosa (logicamente) costituirebbe un insieme nullo ... (anche se sei completamente nudo su un'isola, i tuoi averi sono un insieme vuoto, non nullo)
Clockwork-Muse

@ X-Zero Ma se sei completamente nudo, "possedimenti nello zaino" potrebbe restituire un set nullo, dal momento che non hai nemmeno uno zaino addosso. Si potrebbe essere un BackpackNotFoundException, ma solo se è veramente inaspettato. Dovrebbe essere uno stato normale, diciamo, in un gioco di sopravvivenza sull'isola.
Izkata,

Il controllo null null è ciò che mi aiuta a dormire la notte.
Gioele B,

6

Mi aspetterei un elenco vuoto. theThingssarebbe ancora un oggetto, ma theThings.Counto theThings.size()ritornerebbe 0.


5

Problemi di progettazione del genere vengono risolti dal modello Null Object

... Invece di utilizzare un riferimento null per comunicare l'assenza di un oggetto (ad esempio un cliente inesistente), si utilizza un oggetto che implementa l'interfaccia prevista, ma il cui corpo del metodo è vuoto. Il vantaggio di questo approccio rispetto a un'implementazione predefinita funzionante è che un oggetto null è molto prevedibile e non ha effetti collaterali: non fa nulla.

Ad esempio, una funzione può recuperare un elenco di file in una directory ed eseguire alcune azioni su ciascuno di essi. Nel caso di una directory vuota, una risposta potrebbe essere quella di generare un'eccezione o restituire un riferimento null anziché un elenco. Pertanto, il codice che prevede un elenco deve verificare che in realtà ne abbia uno prima di continuare, il che può complicare la progettazione ...

Suggerimento particolarmente applicabile nel tuo caso (che ritorna Listquando non ci sono Thing) è:

... Restituendo invece un oggetto null (cioè un elenco vuoto ), non è necessario verificare che il valore restituito sia in realtà un elenco. La funzione di chiamata può semplicemente iterare l'elenco normalmente, senza fare nulla. Tuttavia, è ancora possibile verificare se il valore restituito è un oggetto null (ad esempio un elenco vuoto) e reagire in modo diverso se lo si desidera.


3

Dovresti, IMHO, restituire un valore VUOTO. Non so di C #, ma in Java abbiamo questo:

  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
L'equivalente C # è Enumerable.Empty<T>(), che restituisce un valore vuoto IEnumerable<T>(vedi msdn.microsoft.com/en-us/library/bb341042.aspx )
Avner Shahar-Kashtan

1
I documenti attuali sono qui: docs.oracle.com/javase/7/docs/api/java/util/Collections.html - i documenti 1.4.2 ora hanno circa dieci anni.
Stuart segna il

2

Vorrei restituire una raccolta vuota rispetto alla restituzione di un valore null perché in questo modo è possibile evitare di scrivere una verifica null nel codice chiamante.


2

Le due soluzioni significano cose diverse.

Se ci sono solo zero delle cose che stai restituendo, restituisci SEMPRE una raccolta vuota! Prendi il caso di un elenco di directory. Se non ci sono file nella directory, si restituisce una raccolta vuota di file.

D'altra parte, se la directory non esiste, non è proprio appropriato. "Non posso restituire nulla" significa qualcosa di completamente diverso. In tal caso, è necessario restituire null o generare un'eccezione a seconda della situazione, non restituire una raccolta vuota come se nulla fosse sbagliato.


Spiegazione molto ragionevole. Il risultato restituito non dovrebbe coprire lo stato non valido, abbiamo eccezioni per questo.
Ivaylo Slavov,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.