score:65

Accepted answer

Seems logical to me.

  • All: Are all numbers in arr greater than zero (meaning there is no number not greater than zero) => true
  • Any: Is there any number in arr that is greater than zero => false

But more important, according to Boolean Algebra:

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

gives true, because it should be the logical opposite of

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

which gives false (actually this is what the above two points say).

score:5

A bit of mathematical perspective: Any and All are generalized versions of || and && operators, just as Sum and Product (not in LINQ) are generalizations of + and *.

Generalized operators when working on empty set return neutral element of the operation. For + this is 0, for * this is 1 so emptyArray.Product() == 1 because 1 is neutral element of * operation (for all a: a * 1 == a), for || this is false (a || false == a) and for && this is true (a || true == a).

Thanks to this generalized operators preserve associativity of the "original" operation, e.g. for Sum: intersect(A,B) == EmptySet; S = union(A,B); S.Sum() == A.Sum() + B.Sum(), and this will work even when one of the sets A or B is empty. In other words it is mathematically convenient to define that generalized operator on empty set returns neutral element.

score:6

The implementation for All returns true if no element is in the list:

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
}

This seems quite counter-intuitive, but that´s how it is implemented.

However the docs are quite clear for the return-value of All:

true if every element of the source sequence passes the test in the specified predicate, or if the sequence is empty;

score:26

The implementation of All shows very clearly why.

    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;
    }

It runs a foreach over the collection. If there are no elements in the collection, it will skip the foreach and will return true.

Interestingly, the implementation on 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;
    }

This cleary shows they're opposites.


Related Query

More Query from same tag