It's dangerous to code alone! Take this.

What happens if you throw null?

Published on 12 Feb 2022.

I recently had this C# question come into my head:

You can throw an exception with something like throw new ArgumentException(), but what if you do throw null; instead?

I had to experiment and see.

Which of the following do you think will happen?

  1. It creates an error that can’t be caught, because no handler can catch null.
  2. Nothing happens because no exception is provided to actually throw.
  3. A not-null exception is thrown.

All of these seemed plausible to me.

The program I used to test this was a simple:

throw null;

This actually gave me a compiler warning:

CS8597: Thrown value may be null.

That’s a warning, not an error. CS8597 really doesn’t have a lot of documentation online, but its description is pretty straightforward. It recognizes this as suspicious. But as a warning, I could still compile and run it.

So what happens? This code crashed! That immediately eliminates Option 2.

Then I saw the output:

Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object
    at Program.<Main>$(String[] args) in C:\Users\RB\source\repos\Sandbox\Program.cs:line 1

That eliminates Option 1 as well.

The exception throwing mechanism isn’t expecting to get a null value. What does other code do when it is fed null but null isn’t allowed? Other code throws a NullReferenceException in this case.

That’s the same thing that happens here. When the exception throwing mechanism is activated, if the exception given to it is actually null, then it will throw a NullReferenceException at that site instead.

And this exception is not special, but just a plain old NullReferenceException. If you have a catch (NullReferenceException), it will catch it. Same with a catch (Exception). For all practical purposes that I can see, it looks like throw null; is functionally identical to throw new NullReferenceException();, other than perhaps being a tiny bit slower. (Though please don’t use throw null; as a shorthand way to throw null reference exceptions!)

I don’t expect that there are many places where you’d attempt a direct throw null;. If I saw that in a pull request, I’d reject it. It’s clearly not what you want.

I suspect scenarios where this actually happens are more subtle. Something more like:

throw MakeException("Kaboom!");

Exception? MakeException(string type)
{
    return type switch
    {
        "Tick Tick Tick" => new ExplosionPendingException(),
        "kaboom!"        => new ExplosionException(),
        _                => null
    };
}

class ExplosionPendingException : Exception { }
class ExplosionException : Exception { }

This code will throw null because the casing on those strings are not a match. That is the real bug here, though seeing a NullReferenceException isn’t going to immediately make you think to check that.

It looks extremely weird to me to see throw without a new immediately following it. I almost never write code this way. But I do occasionally see code along these lines, including in the Base Class Library. So at least some C# programmers do occasionally write code like this.

Is CS8597 warning associated with the other nullability warnings?

There’s one final thing I wanted to try. I got a compiler warning that I was potentially throwing null. It got me wondering if I’d still see that warning if I didn’t have the Nullable project setting enabled, which is intended to give you warnings when your code doesn’t appear to be handling null or potential null values correctly.

So I turned that project setting to Disabled, and the warning went away. (The behavior remained the same.)

I knew that the Nullable project setting affected compiler warnings. I don’t think I really grasped just how many flavors of warnings there are in this category. It turns out that there’s about 40 of them, though on most days, there’s probably only about four flavors that I actually bump into.