86

When calling Any() on a null object, it throws an ArgumentNullException in C#. If the object is null, there definitely aren't 'any', and it should probably return false.

Why does C# behave this way?

3
  • 7
    null and an empty sequence are something different. Commented Jul 18, 2012 at 9:28
  • 2
    This question provides some useful ways to implement the null check if you find it clunky to do it manually everytime before using .Any() Commented Feb 10, 2017 at 14:13
  • I realize this is an ancient question, but I love your user name! LOL Commented Jul 25, 2023 at 12:47

10 Answers 10

180

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().

6
  • 44
    There is no spoon Commented Mar 12, 2018 at 8:41
  • 1
    So I wonder why there isn't a AnyOrDefault option then... to handle the "there is no spoon" scenario...
    – Dscoduc
    Commented Jan 5, 2020 at 0:09
  • 5
    @Dscoduc You can use ?.Any() ?? false or ?.Any() == true. Alternatively .OrEmpty().Any() if you want to use the extension method from my answer. Commented Jan 10, 2020 at 11:25
  • 1
    @Dscoduc I just use this extension to check if empty or null public static bool IsNullOrEmpty<T>(this IEnumerable<T> list) => list == null || !list.Any();
    – azurez27
    Commented Jan 13, 2020 at 16:47
  • 3
    That's the point of the question though. Every project I've worked on (most) have a similar extension method. Why not have built in NotNull() or NotNullOrAny() method
    – msteel9999
    Commented Sep 2, 2022 at 7:30
83

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!

5
  • 1
    This is a good solution, but if you are doing it frequently, writing your own extension method that does precisely this would be cleaner, especially if you were embedding this into a ternary expression or some such. Commented May 9, 2018 at 6:45
  • 6
    public static bool IsNullOrEmpty<T>(this IEnumerable<T> source) { return source?.Any() != true; } similar to String.IsNullOrEmpty(stringything) Commented Sep 20, 2018 at 18:24
  • 4
    Minor opinion: personally I find if (foo?.Any() == true) easier to grasp than .. ?? false). The former in English is "if any is true then ..", whereas the latter is inherently a two-step logical statement; harder to paraphrase. Its something like "if any (but treat null as false) then ..". Commented Nov 27, 2018 at 8:30
  • 2
    Alternative names for AnyOrDefault might be HasItems or to be more explicit AnyAndNotNull. And FWIW, "Default" in your AnyOrDefault would refer to Default for type of Source, i.e. "null" for an IEnumerable - has nothing to do with Boolean's default of "false". So the name is misleading, because AnyOrDefault logically would mean "Any or null (because that is the default)", so would return true for null. Which is obviously not what you mean. Commented Nov 27, 2018 at 8:34
  • It should be called HasItems() now whether empty list or null the name still correct Commented Apr 23, 2019 at 18:39
59

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!

3
  • It might be worth mentioning why making distinction between an empty collection and an uninitialized collection is important. The only thing I can think of is that it tells you if the collection is taking up space in memory, but then I'm hardly a C# guru.
    – ocket8888
    Commented Jul 8, 2016 at 16:17
  • 8
    While this is correct, I believe these are outdated semantics. What someone typically wants out of an "Any()"/"Where()"/"Select()"/etc. call or even a "foreach" iteration for that matter is to know if there is anything there and to do something if there is something there. So much code waste exists on pointless instantiations or null checks. We got the ?. operator. Go full bore and give us decent null capabilities on extension methods. Commented May 9, 2018 at 6:56
  • Bad bad bad idea, to help helpless progs... need to use a crumpy (Source?.Any()).GetValueOrDefault() to make a simple check for emptiness 'OR' not existence on a strict on scenario... bad decision from the linq guys: they should always remember that their stuff is for people who know what they are doing and not for people who are clueless like me! :/
    – Shockwaver
    Commented Jun 18, 2018 at 11:01
6

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);
3

The Any method runs against an IEnumerable and tells you whether there are any items in the Enumerable. If you don't give it anything to enumerate then an ArgumentNullException is reasonable: a collection with no (matching) elements is different to no collecion.

0
3

Because Any() it is a extension method like this:

public static bool Any(this IEnumerable enumerable)
{
    if (enumerable == null)
        throw ArgumentNullException("enumerable");
    ...
}
1

As others have already mentioned, Any checks whether or not a sequence contains elements. It does not prevent you from passing null values(what might the bug in the first place).

Every extension method in Enumerable class throws an an ArgumentNullException if the source is null. Throwing ArgumentNullExceptions in extensions actually is good practise.

1

Ultimately, the distinction is due to the behavioral differences between no elements and null.

Any() internally first checks that if the source is null, if so, throws an ArgumentNullException (Does not return a bool in this case). Otherwise, it attempts to access the underlying sequence (IEnumerable). If at least one element exists in the sequence, than true is returned, otherwise false. The thing to note here is technically there is three returns, true/false + throwing an ArgumentNullException that could be caught (something that can be caught, hence technically a return).

At first, it may sounds like it should just return false if the source is null since in a way could mean none.

However, there is different levels of information and behavior occurring here. What does no elements and null really mean?

Behaviors of Any()

  • returns true if at least one element exists in the sequence.
  • returns false when a collection with 0 elements.
  • Throws NullReferenceException when the sequence (underlying IEnumerable type) is null.

What does null really mean?

null in all contexts simply means nothing; no data, no memory pointer. null is not a collection, nor an object. It represents an absence in memory. When the computer is "reading memory", it is attempting to read values stored in memory from a particular location. If the memory reader operation encounters the special null character aka 'null terminator' \0, the CPU knows it cannot read this part in memory. Null also means no memory to describe an object or value of some kind. In your example, the underlying IEnumerable object you are calling Any() on doesn't exist, just a null terminator \0. Attempting to read a memory address thats contains only a null terminator will throw a fatal exception. A NullReferenceException if unhandled will terminate every program as defined by the operating system or other software layer(s) right below the application you're running.3

TLDR

  • Any() on a collection with 0 elements is still a collection.
  • null isn't a collection, nor object, nor value. Just nothing.

Practical Real World Example

If you have a wallet) that can hold money inside (the underlying sequence), with no cash (elements) inside, you have a wallet, but your broke (no elements). Null means you don't even have a wallet to put cash inside. The wallet and the cash do not exist.

Lastly, Defending this behavior of null

Attempting to access something doesn't exist should fatally crash a program because its impossible. Something impossible can't be executed. This is true in the case of many, if not all languages.

As @msteel9999 mentions, in either scenario, you're still broke. :D

1
  • If you don't have a wallet you're still broke :)
    – msteel9999
    Commented Sep 2, 2022 at 7:29
0

Any() is an extension method that throws ArgumentNullException if the source is null. Would you perform an action on nothing? In general, it's better to get some explicit indicator of what's happening in the code rather than the default value.

But it doesn't mean it can't be like that. If you know what you doing, write your own custom implementation.

I just wanted to share with you some practical advice my company is following. We write our custom packages shared with private NuGet that are widely used in our products. Checking if the list is null/empty is very frequent, so we decided to write our implementation of Any which makes our code shorter and simpler.

0

There is a method in the .Net Framework for this, why they hid it here, who knows...

namespace Microsoft.IdentityModel.Tokens
{
    /// <summary>
    /// A class which contains useful methods for processing collections.
    /// </summary>
    public static class CollectionUtilities
    {
        /// <summary>
        /// Checks whether <paramref name="enumerable"/> is null or empty.
        /// </summary>
        /// <typeparam name="T">The type of the <paramref name="enumerable"/>.</typeparam>
        /// <param name="enumerable">The <see cref="IEnumerable{T}"/> to be checked.</param>
        /// <returns>True if <paramref name="enumerable"/> is null or empty, false otherwise.</returns>
        public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable)
        {
            return enumerable == null || !enumerable.Any();
        }
    }
}

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