54

I've been discussing this with colleagues, and we couldn't figure out what the use is of .Any for any given List<>, in C#.

You can check the validity of an element in the array like the following statement:

if (MyList.Any()){ ...}  //Returns true or false

Which is exactly the same as

if (MyList.Count() != 0) { ... }

and is much more common, readable and clear about the intent of the if statement.

In the end, we were stuck with this thought:

.Any() can be used, will work just as well, but is less clear about the intent of the programmer, and it that case it should not be used.

But we feel like this can't be right; we must be missing something.

Are we?

13
  • 44
    in what way is any less clear on intent?
    – jk.
    Sep 4, 2015 at 19:40
  • 39
    I challenge your claim that Any() is less clear: Any() seems more clear to me, especially with a lambda-condition. Translating code to English in my head, if(MyList.Count(o => o > 10) > 0) becomes "Is the number of items greater than 10 more than 0?" whereas if(MyList.Any(o => o > 10)) becomes "Are there any items greater than 10?" Sep 4, 2015 at 21:32
  • 3
    @SargeBorsch - only if you prefer Heskel/functional naming, which most people don't. Sep 5, 2015 at 8:14
  • 4
    @BlueRaja-DannyPflughoeft i agree. I think any is more clear since it eliminates a what could be considered a magic number.
    – Andy
    Sep 5, 2015 at 19:49
  • 2
    @SargeBorsch: The SQL parallel to Any is Exists. The Linq name is probably more inspired by Haskell and Python which also have any/all functions.
    – JacquesB
    Sep 6, 2015 at 11:53

5 Answers 5

108

Keep in mind that Any doesn't operate on a List; it operates on an IEnumerable, which represents a concrete type that may or may not have a Count property. It's true that it's not necessarily the best thing to use on a List, but it definitely comes in handy at the end of a LINQ query. And even more useful than the standalone version is the override that takes a predicate just like Where. There's nothing built in on List that's anywhere near as convenient or expressive as the predicate-Any extension method.

Also, if you're using Count() (the LINQ extension method for IEnumerable), rather than Count (the property on List), it can have to enumerate the entire sequence if it can't optimize this away by detecting that your underlying data type has a Count Property. If you have a long sequence, this can be a noticeable performance hit when you don't really care about what the count is, and just want to know if there are any items in the collection.

3
  • 20
    This. Performance aside, Any() with a predicate is more expressive than comparing the override of Enumerable.Count() that takes a predicate with 0. :)
    – Dan J
    Sep 4, 2015 at 19:54
  • 1
    I think this explains the fundamentals so clearly that explains the answer at best.
    – Tarik
    Sep 8, 2015 at 16:44
  • 2
    IMHO, Exists is just as convenient and expressive as Any, with a predicate. Using Count != 0 property on a List is more normal than using Any(). It's just personal preference. I've also gone through the effort of changing _list_.Count() to _list_.Count in my group's code. It made a noticeable difference to me.
    – Suncat2000
    May 25, 2017 at 14:43
61

There is a run time difference Count() can be O(n) where Any() is O(1).

7
  • 20
    Count() also will not halt for infinite iterators, while Any() will, since it only needs to call MoveNext() once.
    – Jon Purdy
    Sep 4, 2015 at 18:31
  • 3
    Succinct and accurate, but this reads more as a comment than an answer. Programmers prefers answers that delve into the why and providing a measure of explanation. Consider editing your answer and expanding upon why O(1) might be (is) important.
    – user53019
    Sep 4, 2015 at 18:40
  • very good answer just learned i should use any instead of count==0 :d Sep 4, 2015 at 18:59
  • 4
    Any(Func<T>) is O(n) Sep 4, 2015 at 21:34
  • 1
    In the specific case of List, performance is the same because the extension uses the property. True for all collections implementing the ICollection interface. Sep 5, 2015 at 7:49
11

Actually, keep in mind that there is the List.Count property, and then there is the Enumerable.Count method.

In your example, you are using the Enumerable.Count() method, which has to iterate through every single item of the enumeration to return a result. That is clearly slower than calling Any() which only needs to iterate over the first item, if it exists.

EDIT:

In the comments it was pointed out, rightly so, that Enumerable.Count() extension method doesn't need to iterate through all the items if it detects that the enumerable also happens to be an ICollection<T>. So in the case of a List<T>, using the Count property or method doesn't actually make a difference.

IEnumerable.Count source:

public static int Count<TSource>(this IEnumerable<TSource> source) {
    if (source == null) throw Error.ArgumentNull("source");
    ICollection<TSource> collectionoft = source as ICollection<TSource>;
    if (collectionoft != null) return collectionoft.Count;
    ICollection collection = source as ICollection;
    if (collection != null) return collection.Count;
    int count = 0;
    using (IEnumerator<TSource> e = source.GetEnumerator()) {
        checked {
            while (e.MoveNext()) count++;
        }
    }
    return count;
}
6
  • Fair enough. What about the use of the .Count property then? wouldn't that make the read significantly faster, maybe as fast or even faster than calling .Any() ?
    – Gil Sand
    Sep 4, 2015 at 18:29
  • 5
    With a List<T> the performance difference will be negligible. So just use what you prefer. But for other types of IEnumerables, you only get to pick between Count() (the method), and Any(), and in that case, Any() will always be the clear winner for your use case and should be preferred. For what it's worth, I think Any() is quite readable and clear.
    – sstan
    Sep 4, 2015 at 18:34
  • @sstan yes unless if the ienumerable can be cast to a collention then it can be optimized and it won't matter. Sep 4, 2015 at 19:10
  • 2
    Count() has the same complexity as Count for ICollections, since the extension method then uses the property instead of iterating. Sep 5, 2015 at 7:38
  • Linq extensions are optimised for known interfaces - IList , ICollection. Performance discussion here is totally redundant, even if that is an implementation detail
    – Gusdor
    Sep 5, 2015 at 17:20
7

A surprising question - I find the intent of list.Any() to be much clearer than the intent of list.Count()!=0.

Intent means: If you read someones code (and you didn't write it yourself), is it completely obvious what the programmer wants to achieve and why it written written like it is? If a common problem is solved in a needlessly complex way, you immediately gets suspicious and wonder why the developer didn't use the simple way. You look through the code and try to see if you have missed something. You are afraid to change the code because you worry there is some side effect you are missing and changing it may cause unexpected problems.

The intent of using the Any() method is completely clear - you want to know if there are any elements in the list or not.

The intent of the expression Count()!=0 on the other hand is not obvious for the reader. It is of course not hard to see that the expression tells you if the list is empty or not. The questions arises because you write it this particular way rather than using the standard method. Why do you use Count() explicitly? If you really just need to know if there are any elements in a list, why do you want to count the whole list first? As soon as you reach 1 you already have have your answer. If the source was an iterator over a large (perhaps infinite) collection or is translated to sql, it could make a big difference performance wise. So maybe the explicit use of Count() is to force a deferred query to execute or to traverse an iterator?

But the source is actually a List<T> where Count() is O(1) and has no side effects. But if the code relies of this property of List<T>, then why not use the Count-property which more clearly indicate that you expect an O(1) operation with no side effects?

As it is written, list.Count()!=0 does exactly the same as list.Any() except it is needlessly more complex and the intent is unclear.

1
  • I read both as, "does the list contain any items?" Count() has an implied conversion that I would avoid using, but it's not unclear. The compiler may optimize it away, which only makes it careless coding.
    – Suncat2000
    May 25, 2017 at 14:53
3

Maybe it's just the word? Any is an adjective, not really saying anything. Coming from Java, I'd call it isNonEmpty which contains a verb. A SQL guy might prefer EXISTS. But maybe Any fits best in the C# system.

Whatever the word choice, once you get used to it, it must be way clearer. Would you ask "Is there more than zero beer bottles left". Would you expect one or more persons starting to count them before they answer "No, there isn't any"?

2
  • 1
    The name "any" makes sense when you think of it in terms of LINQ: Any() is really a shortcut for Any(o => true) Sep 4, 2015 at 23:30
  • I wouldn't normally use empty to describe if an enumerable had anytjing to enumerate over. But "is there anything to enumerate" seems natural to me, and Any works against any enumeration.
    – Andy
    Sep 5, 2015 at 19:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.