Comportement attendu lorsqu'une demande de collection ne contiendra aucun élément

13

Disons que l'on vous donne ce qui suit ...

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

S'il n'y avait rien à retourner, à quoi vous attendriez-vous que fubar.Things.All () revienne?

Edit: Merci pour les opinions. J'attendrai un peu et accepterai l'entrée avec le plus grand nombre.

Je suis d'accord avec les réponses jusqu'à présent, en particulier celles suggérant une collection vide. Un fournisseur a fourni une API avec plusieurs appels similaires à l'exemple ci-dessus. Un fournisseur qui a réalisé un chiffre d'affaires de 4,6 millions de dollars via ses API l'an dernier, BTW. Ils font quelque chose avec lequel je suis fondamentalement en désaccord - ils lèvent une exception.

abscode
la source
Semble être un consensus assez solide [ici] [1]: Collection vide. Toujours. [1]: stackoverflow.com/questions/1969993/…
Jesse C. Slicer
À quoi sert le type de données Things? S'il est logique que le Thingschamp renvoie null, il est logique que vous receviez une exception car vous n'avez pas vérifié null avant votre appel à All(). Cependant, je suis d'accord avec les gens qui pensent fubar.Thingsdevoir retourner une collection vide au lieu de null.
Colin D
Je vois où tu veux en venir, Colin. Dans ce cas, vous pouvez supposer que les choses existent et que All () est statique. L'exception est spécifique à la collection étant vide, pas pour une autre raison.
abscode
OMG ils jettent une exception ...! o_O
Stuart marque
Maintenant, la question la plus intéressante serait quelle raison sur terre n'importe qui pourrait avoir à lancer dans un cas aussi générique, ou qu'est - ce qui rend le cas si spécial pour justifier le lancement ??!
Martin Ba

Réponses:

29

Parmi les deux possibilités (c'est-à-dire retourner une nullou retourner une collection vide), je choisirais de retourner une collection vide, car cela permet à l'appelant de sauter une vérification de la valeur retournée. Au lieu d'écrire ceci

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

ils pourraient écrire ceci:

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

Ce deuxième fragment de code est plus court et plus facile à lire, car le niveau d'imbrication est inférieur de un.

dasblinkenlight
la source
2
Je pense que je trouverais aussi plus facile à comprendre conceptuellement que «l'ensemble est vide» (aucun élément). Null, c'est «il n'y a pas d'ensemble», ce qui est assez différent. (Cela devrait également couvrir les choses qui sont des impossibilités logiques - l'ensemble de tous les éléments qui sont impairs qui sont également pairs doit être vide, et non nul). Je ne suis honnêtement pas sûr de ce qui (logiquement) constituerait un ensemble nul ... (même si vous êtes nu sur une île, vos biens sont un ensemble vide, pas nul)
Clockwork-Muse
@ X-Zero Mais si vous êtes nu, "les possessions dans le sac à dos" peuvent renvoyer un ensemble nul, car vous n'avez même pas de sac à dos sur vous. Il peut s'agir d'une exception BackpackNotFoundException, mais uniquement si elle est vraiment inattendue. Cela devrait être un état normal dans, disons, un jeu de survie insulaire.
Izkata
Le chèque nul supplémentaire est ce qui m'aide à dormir la nuit.
Joel B
6

Je m'attendrais à une liste vide. theThingsserait toujours un objet, mais theThings.Countou theThings.size()reviendrait 0.

David Hogue
la source
5

Les problèmes de conception comme celui-ci sont résolus par le modèle d'objet nul

... Au lieu d'utiliser une référence nulle pour transmettre l'absence d'un objet (par exemple, un client inexistant), on utilise un objet qui implémente l'interface attendue, mais dont le corps de la méthode est vide. L'avantage de cette approche par rapport à une implémentation fonctionnelle par défaut est qu'un objet nul est très prévisible et n'a aucun effet secondaire: il ne fait rien.

Par exemple, une fonction peut récupérer une liste de fichiers dans un répertoire et effectuer une action sur chacun. Dans le cas d'un répertoire vide, une réponse peut être de lever une exception ou de renvoyer une référence nulle plutôt qu'une liste. Ainsi, le code qui attend une liste doit vérifier qu'elle en a bien une avant de continuer, ce qui peut compliquer la conception ...

La suggestion particulièrement applicable dans votre cas (retour Listlorsqu'il n'y a pas de Things) est:

... En renvoyant à la place un objet nul (c'est-à-dire une liste vide ), il n'est pas nécessaire de vérifier que la valeur de retour est bien une liste. La fonction appelante peut simplement parcourir la liste normalement, sans rien faire. Il est cependant toujours possible de vérifier si la valeur de retour est un objet nul (par exemple une liste vide) et de réagir différemment si souhaité.

moucheron
la source
3

Vous devriez, à mon humble avis, retourner une valeur VIDE. Je ne connais pas C #, mais en Java, nous avons ceci:

  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

Marcelo Assis
la source
1
L'équivalent C # est Enumerable.Empty<T>(), qui renvoie un vide IEnumerable<T>(voir msdn.microsoft.com/en-us/library/bb341042.aspx )
Avner Shahar-Kashtan
1
Les documents actuels sont ici: docs.oracle.com/javase/7/docs/api/java/util/Collections.html - les documents 1.4.2 ont maintenant environ dix ans.
Stuart marque
2

Je retournerais une collection vide au-dessus de renvoyer une valeur nulle parce que de cette façon vous pouvez éviter d'écrire une vérification nulle dans le code appelant.


la source
2

Les deux solutions signifient des choses différentes.

S'il n'y a rien de ce que vous retournez, vous retournez TOUJOURS une collection vide! Prenons le cas d'une liste d'annuaire. S'il n'y a aucun fichier dans le répertoire, vous retournez une collection vide de fichiers.

En revanche, si le répertoire n'existe pas, ce n'est pas vraiment approprié. «Je ne peux rien retourner» signifie quelque chose de complètement différent. Dans ce cas, vous devez retourner null ou lever une exception en fonction de la situation, ne renvoyez pas simplement une collection vide comme si de rien n'était.

Bill K
la source
Explication très raisonnable. Le résultat retourné ne doit pas couvrir l'état invalide, nous avons des exceptions pour cela.
Ivaylo Slavov