Why doesn't Any() work on a c# null object

Any() is asking: "Does this box contain any items?"

If the box is empty, the answer is clearly no.

But if there is no box in the first place, then the question makes no sense, and the function complains: "What the hell are you talking about? There is no box."


When I want to treat a missing collection like an empty one, I use the following extension method:

public static IEnumerable<T> OrEmpty<T>(this IEnumerable<T> sequence)
{
    return sequence ?? Enumerable.Empty<T>();
}

This can be combined with all LINQ methods and foreach, not just .Any().


With modern C#, you can easily handle the OP's scenario with a simple check like this:

List<string> foo = null;

if (foo?.Any() ?? false)
{
    DoStuff();
}

This is kinda like a lame AnyOrDefault(bool default) implementation that the OP is expecting the Any() extension method to do.

You could easily make this into an extension like this:

public static bool HasItems<T>(this IEnumerable<T> source)
{
    return (source?.Any() ?? false);
}

Honestly, I don't really like the name AnyOrDefault for this since it won't ever make sense to pass in a default value (a default of true would probably be pretty mean to people reading code later). Renamed to HasItems, as suggested in the comments. This is a far better name!


When dealing with reference types, a null value is semantically different from an "empty" value.

A null string is not the same as string.Empty, and a null IEnumerable<T> is not the same as Enumerable.Empty<T> (or any other "empty" enumerable of that type).

If Any were not an extension method, calling it on null would result in NullReferenceException. Since it is an extension method, throwing some exception (although not necessary) is a good idea because it preserves the well-known semantics of trying to call a method on null: BOOM!


Any() is an extension method, so this is actually passed as the first argument to the method. In this situation, it's understandable for it to throw ArgumentNullException is this is null.

You can perform the check yourself beforehand:

bool hasAny = yourData == null ? false : yourData.Any(yourPredicate);