What Is the NullReferenceException?
Learn when a NullReferenceException is thrown.
We'll cover the following...
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.
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.
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.
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
Movieclass and add anIsAGoodMovie()method to check if its rating is greater than five. Then, on line 3, use theIsAGoodMovie()method instead of accessing theNameproperty. Do we still get aNullReferenceException?
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 staticPrintMovie()method that receives a movie and prints out its name. Then, on line 3, let’s use this new method, passing the result ofFindMovie(). Do we still get aNullReferenceException?
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:
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.