Coder Perfect

Not Any vs. All Don’t in LINQ

Problem

Often I want to check if a provided value matches one in a list (e.g. when validating):

if (!acceptedValues.Any(v => v == someValue))
{
    // exception logic
}

Recently, ReSharper has been requesting that I simplify these queries to:

if (acceptedValues.All(v => v != someValue))
{
    // exception logic
}

Obviously, this is logically identical, and probably slightly more understandable (if you’ve done a lot of arithmetic), but does it result in a performance penalty?

It seems like it should (i.e..Any() seems like it short-circuits, whereas.Any() sounds like it doesn’t). All() appears to do so, but I have no evidence to back this up. Is there anyone who knows whether the queries will resolve the same way, or if ReSharper is leading me astray?

Asked by Mark

Solution #1

According to ILSpy, all should be implemented (as in I actually went and looked, rather than the “well, that method works a bit like …” I might do if we were discussing the theory rather than the impact).

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 current in source)
    {
        if (!predicate(current))
        {
            return false;
        }
    }
    return true;
}

ILSpy’s implementation of Any is as follows:

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 current in source)
    {
        if (predicate(current))
        {
            return true;
        }
    }
    return false;
}

Of fact, there could be a minor discrepancy in the IL that is produced. But there isn’t any. Except for the obvious reversal of returning true on predicate match versus returning false on predicate mismatch, the IL is nearly identical.

Of course, this is only for linq-for-objects. It’s possible that another linq provider treats one significantly better than the other, but if that’s the case, which one gets the better implementation is pretty much random.

It appears that the rule is based purely on the belief that if(determineSomethingTrue) is more legible and simpler than if(!determineSomethingFalse). And in fairness, I think they’ve a bit of a point in that I often find if(!someTest) confusing* when there’s an alternative test of equal verbosity and complexity that would return true for the condition we want to act upon. Yet really, I personally find nothing to favour one over the other of the two alternatives you give, and would perhaps lean very slightly toward the former if the predicate were more complicated.

*Not confusing in the sense that I don’t understand it, but perplexing in the sense that I’m worried there’s some hidden rationale behind the decision, and it takes a few mental skips to realize that “no, they just decided to do it that way, wait what was I looking at this section of code for again?”

Answered by Jon Hanna

Solution #2

These extension methods may help you make your code more readable:

public static bool None<TSource>(this IEnumerable<TSource> source)
{
    return !source.Any();
}

public static bool None<TSource>(this IEnumerable<TSource> source, 
                                 Func<TSource, bool> predicate)
{
    return !source.Any(predicate);
}

Instead of your original, you’ll now have

if (!acceptedValues.Any(v => v == someValue))
{
    // exception logic
}

you could say

if (acceptedValues.None(v => v == someValue))
{
    // exception logic
}

Answered by AakashM

Solution #3

Both would have the same performance because they both end enumeration when the result can be known – Any() on the first item evaluates to true and All() on the first item evaluates to false.

Answered by BrokenGlass

Solution #4

It’s not a problem because everything short circuits on the first non-match.

There is a level of subtlety in this area.

 bool allEven = Enumerable.Empty<int>().All(i => i % 2 == 0); 

Is correct. The sequence has an even number of entries.

Consult the Enumerable.All documentation for more information on this method.

Answered by Anthony Pegram

Solution #5

This isn’t about performance; it’s about clarity, as other answers have stated.

Both of your options have a lot of support:

if (!acceptedValues.Any(v => v == someValue))
{
    // exception logic
}

if (acceptedValues.All(v => v != someValue))
{
    // exception logic
}

However, I believe that this will garner more support:

var isValueAccepted = acceptedValues.Any(v => v == someValue);
if (!isValueAccepted)
{
    // exception logic
}

In my perspective, simply computing the boolean (and identifying it) before negating anything clarifies this a lot.

Answered by Michael Haren

Post is based on https://stackoverflow.com/questions/9027530/linq-not-any-vs-all-dont