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 Renamed to 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).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);