142 votes

Pourquoi Enumerable.All renvoie true pour une séquence vide?

         Collection<string> strs = new Collection<string>();
        bool b = strs.All(str => str == "ABC");
 

Le code crée une collection vide de chaînes, puis essayez de déterminer si tous les éléments de la collection sont "ABC". Si vous l'exécutez, b sera vrai.

Mais la collection ne contient même aucun élément, encore moins d’éléments équivalents à "ABC".

Est-ce un bug? Ou y a-t-il une explication raisonnable?

Merci

203voto

Jon Skeet Points 692016

Ce n'est certainement pas un bug. C'est à se comporter exactement comme indiqué:

vrai si chaque élément de la séquence source passe le test spécifiée dans le prédicat, ou si la séquence est vide; sinon, false.

Maintenant, vous pouvez discuter sur si oui ou non il doit travailler de cette façon (il me semble bien pour moi; chaque élément de la séquence est conforme à l'prédicat), mais la première chose à vérifier avant de vous demander si quelque chose est un bug, est la documentation. (C'est la première chose à vérifier dès qu'une méthode se comporte d'une manière autre que ce que vous attendiez.)

22voto

Mr. Putty Points 1101

Tous, il faut le prédicat être vrai pour tous les éléments de la séquence. C'est explicitement indiqué dans la documentation. C'est aussi la seule chose qui a de sens que si vous pensez à Tous comme à un et logique entre le prédicat de résultats pour chaque élément. Le "vrai" que vous sortez pour la séquence vide est l'élément identité de l'opération. De même, le faux que vous obtenez à partir de la séquence vide est l'identité de vue logique.

Si vous pensez à "tous" comme "il n'y a pas d'éléments dans la séquence qui ne le sont pas", cela pourrait faire plus de sens.

11voto

leppie Points 67289

Il s'agit de true , car rien (aucune condition) ne le rend false .

Les docs l'expliquent probablement. (Jon Skeet a également mentionné quelque chose il y a quelques années)

Il en va de même pour Any (l'inverse de All ) renvoyant false pour les ensembles vides.

Modifier:

Vous pouvez imaginer que All soit implémenté de la même manière que:

 foreach (var e in elems)
{
  if (!cond(e))
    return false;
}
return true; // no escape from loop
 

5voto

Andrew Barber Points 25990

La méthode parcourt tous les éléments jusqu'à ce qu'elle en trouve un qui ne remplit pas la condition ou n'en trouve aucun qui échoue. Si aucun échoue, true est renvoyé.

Donc, s'il n'y a pas d'éléments, true est renvoyé (puisqu'il n'y en avait aucun qui a échoué)

1voto

Hasan Khan Points 20723

Garder la mise en œuvre de côté. Est-ce vraiment important si c'est vrai? Voyez si vous avez du code qui parcourt l'énumérable et l'exécute. Si All () est vrai, le code ne sera toujours pas exécuté car l'énumérable ne contient aucun élément.

 var hungryDogs = Enumerable.Empty<Dog>();
bool allAreHungry = hungryDogs.All(d=>d.Hungry);    
if (allAreHungry)
    foreach (Dog dog in hungryDogs)
         dog.Feed(biscuits); <--- this line will not run anyway.
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X