36 votes

C # Linq All & Any travaillant différemment sur un tableau vide

Envisagez de suivre l'exemple linq avec un tableau vide:

Lorsque Any() renvoie false car il n'y a pas de nombre supérieur à zéro, comment All() renvoyer true indiquant tous les nombres supérieurs à zéro?

 var arr = new int[] { };
Console.WriteLine(arr.Any(n => n > 0)); //false 
Console.WriteLine(arr.All(n => n > 0)); //true 
 

59voto

René Vogt Points 2704

Semble logique pour moi.

  • All: Sont tous les nombres en arr supérieure à zéro (ce qui signifie il n'y a pas de numéro pas de plus grande que zéro) => true
  • Any: Est-il tout nombre en arr qui est supérieur à zéro => false

Mais le plus important, en fonction de l'Algèbre Booléenne:

arr.All(n => n > 0); 

donne true, parce que ça devrait être la logique inverse de

arr.Any(n => !(n > 0));

ce qui donne false (en fait c'est ce que les deux points précités dire).

24voto

No1_Melman Points 1516

La mise en œuvre de All montre très clairement pourquoi.

     public static bool All<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
        if (source == null) throw Error.ArgumentNull("source");
        if (predicate == null) throw Error.ArgumentNull("predicate");
        foreach (TSource element in source) {
            if (!predicate(element)) return false;
        }
        return true;
    }
 

Il fonctionne à foreach sur la collection. S'il n'y a pas d'éléments dans la collection, les foreach seront ignorés et retourneront vrais.

Fait intéressant, la mise en œuvre sur Any

     public static bool Any<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
        if (source == null) throw Error.ArgumentNull("source");
        if (predicate == null) throw Error.ArgumentNull("predicate");
        foreach (TSource element in source) {
            if (predicate(element)) return true;
        }
        return false;
    }
 

Cela montre clairement qu'ils sont opposés.

5voto

HimBromBeere Points 8328

La mise en œuvre de All retourne true si aucun élément n'est dans la liste:

public static bool All<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
    if (source == null) throw Error.ArgumentNull("source");
    if (predicate == null) throw Error.ArgumentNull("predicate");
    foreach (TSource element in source) {
        if (!predicate(element)) return false;
    }
    return true;  // watch this
}

Cela semble tout à fait contre-intuitif, mais c'est comment il est mis en œuvre.

Cependant, les docs sont tout à fait claires pour le retour de la valeur de All:

vrai si chaque élément de la séquence source passe le test de la principales spécifiques, ou si la séquence est vide;

3voto

csharpfolk Points 2683

Un peu de perspective mathématique: Any et All sont des versions d' || et && opérateurs, tout comme Sum et Product (pas dans LINQ) sont des généralisations + et *.

Généralisée des opérateurs lors du travail sur le vide de retour est élément neutre de l'opération. Pour + c'est 0, pour * c'est 1 donc, emptyArray.Product() == 1 parce que 1 est l'élément neutre de l' * de l'opération (pour tous: a * 1 == a), pour || c'est false (a || false == a) et pour && c'est true (a || true == a).

Grâce à cette généralisé opérateurs de préserver l'associativité de l ' "original" de l'opération, par exemple pour la Somme: intersect(A,B) == EmptySet; S = union(A,B); S.Sum() == A.Sum() + B.Sum(), et ce même lorsque l'un des ensembles A ou B est vide. En d'autres termes, il est mathématiquement très pratique pour définir qui généralisée de l'opérateur sur l'ensemble vide renvoie élément neutre.

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