TL;DR: Any()
will in fact call ICollection.Count
, if the collection type implements it. Otherwise it will try and pick the "best" way of checking if the collection is non-empty.
Checking for null
is quite different to checking for empty, and it doesn't really make sense to compare it with empty checks.
Paul Kertscher has already answered the meat of your question, but to help with future queries on this sort of thing it is well worth remembering that the source code for dotnet is, in fact, available online.
The code for the LINQ Any()
method, for example, may be found here: https://github.com/dotnet/runtime/blob/main/src/libraries/System.Linq/src/System/Linq/AnyAll.cs (and there's plenty more in the rest of the runtime repo, with the libraries here). It is a little more complex than the version of the method that Paul included in his answer... possibly he's referencing a different version of the runtime. Here's the latest implementation though (comments present in original source):
public static bool Any<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
}
if (source is ICollection<TSource> collectionoft)
{
return collectionoft.Count != 0;
}
else if (source is IIListProvider<TSource> listProv)
{
// Note that this check differs from the corresponding check in
// Count (whereas otherwise this method parallels it). If the count
// can't be retrieved cheaply, that likely means we'd need to iterate
// through the entire sequence in order to get the count, and in that
// case, we'll generally be better off falling through to the logic
// below that only enumerates at most a single element.
int count = listProv.GetCount(onlyIfCheap: true);
if (count >= 0)
{
return count != 0;
}
}
else if (source is ICollection collection)
{
return collection.Count != 0;
}
using (IEnumerator<TSource> e = source.GetEnumerator())
{
return e.MoveNext();
}
}
The code for ICollection
is part of System.Collection, and IListProvider
is part of System.Linq.
You can see that there's multiple ways in which Any()
can test if the underlying collection has any items in it, and you can reasonably assume that they're tried in order of speed/efficiency. Obviously, you could write a terribly implementation of ICollection.Count { get }
, but that would be a silly thing to do and it would be nice to think that Microsoft haven't done that in any of the collection types that ship with the dotnet runtime. (incidentally, arrays implement ICollection.Count
via an explicit interface, which maps it to their Length
property, which is why Any()
doesn't need to care about checking for Length
)
I haven't looked up any implementations of IListProvider<T>.GetCount
,. The docs for the interface method say this:
If true then the count should only be calculated if doing so is quick (sure or likely to be constant time), otherwise -1 should be returned.
Again, terrible implementations could exist, but probably don't.
There's generally nothing wrong with using Any()
instead of Count
. The additional overhead in calling a method and running through a few ifs and casts is generally negligible. Just make sure not to confise Count
with Count()
, as the latter may require traversing the whole of a collection which can be a comparatively expensive and time consuming thing to do, and is quite pointless if all you you want to do is check for emptiness.