310

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, I've noticed ReSharper asking me to simplify these queries to:

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

Obviously, this is logically identical, perhaps slightly more readable (if you've done a lot of mathematics), my question is: does this result in a performance hit?

It feels like it should (i.e. .Any() sounds like it short-circuits, whereas .All() sounds like it does not), but I have nothing to substantiate this. Does anyone have deeper knowledge as to whether the queries will resolve the same, or whether ReSharper is leading me astray?

Jon Hanna
  • 110,372
  • 10
  • 146
  • 251
Mark
  • 3,372
  • 2
  • 16
  • 14
  • 6
    Have you tried disassembling the Linq code to see what it's doing? – RQDQ Jan 27 '12 at 00:33
  • 9
    In this case I would actually go with if(!acceptedValues.Contains(someValue)), but of course this was not the question :) – csgero Apr 12 '12 at 16:13
  • 2
    @csgero I agree. The above was a simplification (perhaps over-simplification) of the real logic. – Mark Oct 03 '12 at 07:17
  • I think "if there is not any value equal to x" is clearer than "if all values are different than x". I wish JetBrains would split the "Simplify LINQ expression" inspection into different types of inspections so I could disable this specific one. – Kevin Coulombe Nov 09 '13 at 19:03
  • 1
    "It feels like it should (i.e. .Any() sounds like it short-circuits, whereas .All() sounds like it does not)" -- Not to anyone with sound intuitions. The are logical equivalence you note implies that they are equally short-circuitable. A moment's thought reveals that All can quit as soon as a non-qualifying case is encountered. – Jim Balter May 16 '14 at 20:07
  • 4
    I do not universally agree with ReSharper on this. Write sensible trains of thought. If you want to throw an exception if a required item is missing: `if (!sequence.Any(v => v == true))`. If you wish to continue only if everything conforms to a certain specification: `if (sequence.All(v => v < 10))`. – Timo Jul 01 '15 at 10:45
  • Be careful with multiple comparisons though as `!Any(v => v.Value == someValue && v.Key == anotherValue)` is not equivalent to `All(v => v.Value != someValue && v.Key != anotherValue)` but is equivalent to `All(v => (!(v.Value == someValue && v.Key == anotherValue))` – Caltor May 04 '20 at 12:35

8 Answers8

373

Implementation of All according to ILSpy (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;
}

Implementation of Any according to ILSpy:

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 course, there could be some subtle difference in the IL produced. But no, no there isn't. The IL is pretty much the same but for the obvious inversion of returning true on predicate match versus returning false on predicate mismatch.

This is linq-for-objects only of course. It's possible that some other linq provider treats one much better than the other, but then if that was the case, it's pretty much random which one got the more optimal implementation.

It would seem that the rule comes down solely to someone feeling that if(determineSomethingTrue) is simpler and more readable 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 as in I don't understand, but confusing as in I worry that there's some subtle reason for the decision that I don't understand, and it takes a few mental skips to realise that "no, they just decided to do it that way, wait what was I looking at this bit of code for again?..."

Jon Hanna
  • 110,372
  • 10
  • 146
  • 251
  • 9
    I'm not sure what is done behind the lines, but for me is much more readable is: if (not any) than if (all not equal). – VikciaR Aug 07 '12 at 06:15
  • 1
    @VikciaR Yes, I agree. That said, in general, I find if(something) more readable than if(not somethingElse). Hence my guess that this is what the rule is looking for, without anything to look for the more specific case where "something" is "all not equal" and "somethingElse" is "any". Of course, I can only guess as to what re-sharper's developers thinking on it was. – Jon Hanna Aug 07 '12 at 11:33
  • 62
    There is a BIG difference when your enumeration has no values. 'Any' would always return FALSE, and 'All' always return TRUE. So saying than one is the logical equivalent of the other is not entirely true! – Arnaud Mar 24 '13 at 22:41
  • 1
    @Arnaud I still don't see the difference. In the context of this example, Any will return false and then be negated to true by the ! in the if statement. All will return true, and so both are still equivalent. – Niall Connaughton Apr 15 '13 at 00:32
  • 53
    @Arnaud `Any` will return `false` and hence `!Any` will return `true`, so they're identical. – Jon Hanna May 30 '13 at 10:31
  • 14
    @Arnaud There is not any person who commented who said that Any and All are logically equivalent. Or to put it another way, all persons who commented did not say that Any and All are logically equivalent. The equivalence is between !Any(predicate) and All(!predicate). – Jim Balter Aug 20 '13 at 05:50
  • I know this is an old thread but I thought I'd point out a key difference between !Any and All when comparing more than one property. Take the following dictionary `var test = new Dictionary { { 1, 1 }, { 2, 1 }, { 3, 2 } };`. As expected `!test.Any(x => x.Key == 3 && x.Value == 1)` will return `true` as there is no entry with key of 3 and value 1. However `test.All(x => x.Key != 3 && x.Value != 1)` will return `false` as it matches the key of 3 and value of 1 separately. With .All() you would need to use `test.All(x => x.Key != 3 || x.Value != 1)` – Macs Dickinson Sep 18 '13 at 13:02
  • 9
    @MacsDickinson that's not a difference at all, because you're not comparing opposite predicates. The equivalent to `!test.Any(x => x.Key == 3 && x.Value == 1)` that uses `All` is `test.All(x => !(x.Key == 3 && x.Value == 1))` (which is indeed equivalent to `test.All(x => x.Key != 3 || x.Value != 1)`). – Jon Hanna Sep 18 '13 at 14:05
  • 1
    I would not say that they are identical by any means, however, they both short circuit once a condition is met. So that being said in some cases, let's say a sorted list, Any() may perform better as the value is found to be true earlier, otherwise the entire list MAY be iterated. Personally, I prefer Any() over All(), but I feel there is little difference and is entirely conditional on the size of the list/array as well as the context. – Anthony Mason May 28 '14 at 15:19
  • 3
    @AnthonyMason no, they will both sort-circuit on the same instance. Size of collection would have zero impact. – Jon Hanna May 28 '14 at 15:33
  • @NetMage no as pointed out by Jon Hanna they will both short-circuit on the same instance. Ordering of data makes no difference. – Caltor May 04 '20 at 11:46
67

You might find these extension methods 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);
}

Now instead of your original

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

you could say

if (acceptedValues.None(v => v == someValue))
{
    // exception logic
}
AakashM
  • 62,551
  • 17
  • 151
  • 186
  • 6
    Thanks - I was already thinking of implementing these in our commons library, but I haven't decided if it is a good idea yet. I agree that they make the code more readable, but I am concerned that they don't add sufficient value. – Mark Jan 28 '12 at 07:17
  • 3
    I looked for None and didn't find it. It is very much more readable. – Rhyous Feb 10 '18 at 02:15
  • I had to add null checks: return source == null || !source.Any(predicate); – Rhyous Feb 10 '18 at 02:23
32

Both would have identical performance because both stop enumeration after the outcome can be determined - Any() on the first item the passed predicate evaluates to true and All() on the first item the predicate evaluates to false.

BrokenGlass
  • 158,293
  • 28
  • 286
  • 335
21

All short circuits on the first non-match, so it's not a problem.

One area of subtlety is that

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

Is true. All of the items in the sequence are even.

For more on this method, consult the documentation for Enumerable.All.

Anthony Pegram
  • 123,721
  • 27
  • 225
  • 246
  • 13
    Yes, but `bool allEven = !Enumerable.Empty().Any(i => i % 2 != 0)` is true too. – Jon Hanna Jan 27 '12 at 00:40
  • 1
    @Jon semantically none != all. So semantically you either have none or all but in the case of .All() none is just a subset of all the collections that return true for all and that discrepancy can result in bugs if you are unaware of it. +1 for that Anthony – Rune FS Jan 27 '12 at 09:33
  • @RuneFS I don't follow. Semantically and logically "none where it is untrue that..." is indeed the same as "all where it is true that". E.g. "where none of the accepted projects from our company?" will always have the same answer as "where all of the accepted projects from other companies?"... – Jon Hanna Jan 27 '12 at 09:59
  • ... Now, it's true that you can have bugs from assuming "all the items are..." means there is at least one item that is at least one item that fulfils the test, since the "all the items..." is always true for the empty set, I don't dispute that at all. I added though that the same problem can happen with assuming "none of the items..." means at least one items doesn't fulfill the test, since "none of the items..." is also always true for the empty set. It's not that I disagree with Anthony's point, its that I think it also holds for the other of the two constructs under discussion. – Jon Hanna Jan 27 '12 at 10:01
  • @Jon you are talking logic and I am talking linguistics. The human brain can't process a negative (before it process the positive at which point it can then negate it) so in that sense there's quite a difference between the two. That doesn't make the logic you propose incorrect – Rune FS Jan 27 '12 at 10:09
  • @RuneFS I grant you that 100% (well, 98% because the human brain can process negatives at some levels or else we wouldn't be able to have this conversation). My point isn't that the two constructs are logically the same (though it is *part* of my point), but that if someone fails to grok the implications of the first in terms of the empty set then they are just as likely to grok the second in the same way. – Jon Hanna Jan 27 '12 at 10:19
  • I will note that I mentioned the area of subtlety because it *has* specifically tripped people up in the past here, and it was even a source of a bug in the application I am presently working on (wasn't *my* bug, not that I haven't accidentally contributed any). At any rate, the important thing is that both the early return and the zero-element behavior are in the linked documentation. – Anthony Pegram Jan 27 '12 at 12:52
  • Yep, certainly worth mentioning it. – Jon Hanna Jan 28 '12 at 09:09
10

All() determines whether all elements of a sequence satisfy a condition.
Any() determines whether any element of a sequence satisfies the condition.

var numbers = new[]{1,2,3};

numbers.All(n => n % 2 == 0); // returns false
numbers.Any(n => n % 2 == 0); // returns true
emy
  • 664
  • 1
  • 9
  • 22
10

As other answers have well covered: this is not about performance, it's about clarity.

There's wide support for both of your options:

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

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

But I think this might achieve broader support:

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

Simply computing the boolean (and naming it) before negating anything clears this up a lot in my mind.

Michael Haren
  • 105,752
  • 40
  • 168
  • 205
  • I am all for well-named "explaining variables" when evaluating conditions, and frequently use them in my code, yet I still come up against resistance sometimes in code reviews as it adds more "unnecessary" lines to the member. However, in your case I would negate the explaining variable so you can read `if (valueIsNotAccepted) { ... }` to get rid of the `!` negation in the parenthesis. – Dib Aug 13 '21 at 08:11
10

If you take a look at the Enumerable source you'll see that the implementation of Any and All is quite close:

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

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

There is no way that one method be significantly faster than the other since the only difference lies in a boolean negation, so prefer readability over false performance win.

Thomas Ayoub
  • 29,063
  • 15
  • 95
  • 142
7

According to this link

Any – Checks for at least one match

All – Checks that all match

rcarvalhoxavier
  • 331
  • 5
  • 7
  • 3
    you are right but they stop at the same time for a given collection. All breaks when condition fails and Any Breaks when it matches your predicate. So Technically no different except scenatically – WPFKK Aug 14 '17 at 21:57