55

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?

Gil Sand
  • 2,193

5 Answers5

111

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.

Mason Wheeler
  • 83,213
65

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

Sign
  • 2,733
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;
}
sstan
  • 211
9

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.

JacquesB
  • 61,955
  • 21
  • 135
  • 189
4

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"?

maaartinus
  • 2,713