What Is the NullReferenceException?

Learn when a NullReferenceException is thrown.

Let’s start by learning when a NullReferenceException is thrown.

Value and reference types

Generally speaking, C# has two kinds of types:

  • Value types are all “primitive” types. These include integers, characters, and booleans.
  • Reference types are more “complex” objects. These include strings and our custom objects.

When we declare a variable of a primitive type without an initial value, it gets assigned a default value. For example, integers are initialized to 0 and booleans to false. But reference types are initialized to null.

int anInt; // -> 0
bool aBool; // -> false
string aString; // -> null

With this context in mind, let’s see when the NullReferenceException is thrown.

When is a NullReferenceException thrown?

A NullReferenceException is thrown when we access a property, field, or method of an uninitialized variable of a reference type.

Let’s write an example that throws a NullReferenceException.

main.cs
NRE.csproj
var movie = FindMovie();
Console.WriteLine(movie.Name);
static Movie FindMovie()
{
// Imagine this is a database call that might
// or might not return a movie
return null;
// Often, in real life, it's more like this:
//var random = new Random();
//return random.NextDouble() >= 0.5
// ? new Movie("Titanic", 1997, 7.9f)
// : null;
}
record Movie(string Name, int ReleaseYear, float Rating)
{
// TODO: Add a IsAGoodMovie method here
}

If we run our previous example without any changes, it throws a NullReferenceException. We should get an error message like the one in the image below.

Error message
Error message

Notice we didn’t write a regular console application. We used top-level and global using statements to simplify our Main class. We didn’t even write a class declaration, and we used a record to declare an immutable Movie class from lines 18 to 21.

In the FindMovie() method from lines 5 to 16, we return null at line 9. We print the Name property at line 3 of the returned value from line 1, which causes a NullReferenceException. This would still be the case even if we had called any method in the Movie class.

Let’s go back to the Movie class and add an IsAGoodMovie() method to check if its rating is greater than five. Then, on line 3, use the IsAGoodMovie() method instead of accessing the Name property. Do we still get a NullReferenceException?

It might seem obvious or silly that we returned null from a method. But it’s not that obvious in other scenarios. The FindMovie() method could be a method that accessed a database and didn’t find any records, or it could be an API controller method that didn’t receive a required input parameter.

Similarly, we could get a NullReferenceException from passing a null as a parameter to a method that uses that parameter in its body.

Let’s go back to the previous example, and below the FindMovie() method, add a static PrintMovie() method that receives a movie and prints out its name. Then, on line 3, let’s use this new method, passing the result of FindMovie(). Do we still get a NullReferenceException?

Don’t catch the NullReferenceException

To fix the NullReferenceException, we might be tempted to write a try/catch block around the code that throws it. Sure enough, that’s what try/catch blocks are for. But let’s not throw or catch the NullReferenceException.

Let’s not write something like this:

try
{
AMethodThatMightThrowNullReferenceException();
}
catch (NullReferenceException)
{
// ...
// Do something with the exception here
}

A NullReferenceException is a symptom of an unhandled and unexpected scenario in our code. Catching it doesn’t handle that. Rather than catching it, we should prevent it in the first place, instead.