NullReferenceException
is the most evil of all exceptions in an application. It means a possibly-null reference wasn't checked for a null value before it was accessed.
It's evil, because the runtime can't determine what you were expecting to find in the reference, so it can't tell you what precisely failed to be de-referenced.
The stack trace is your only friend in this exception, where it can at least identify which method threw the exception. If your code is neat enough, it should identify a small amount of code to check through.
Additionally, if you're running with a debug build and have the debugging information with the assemblies, you'll even get source line numbers in the stack trace, so you can know exactly what line the method failed on.
The real answer is to prevent this exception from ever being thrown. It's an indicator that some code was poorly written, failing to deal with the scenario where a reference was null
.
If you have a method being called where you need to do something with a reference-type argument that needs to be de-referenced at some point, check for null
and throw ArgumentNullException
, indicating the name of the parameter:
if(parameter == null)
throw new ArgumentNullException("parameter");
If you are performing an operation within a class and a settable property can be set to null
, check before de-referencing it and throw an InvalidOperationException
indicating the problem:
if(Property == null)
throw new InvalidOperationException("Property cannot be null.");
You should also make sure that all methods you're calling that can return reference types are guaranteed to return a value. For all those that are not, make similar checks for null
and handle the case appropriately.
EDIT:
To clarify, I'm not suggesting you perform a check on every reference-type variable before you de-reference it. That would be madness.
It's about understanding where a variable can be assigned null
and where it cannot. If you assign a private field in a class to a non-null value in the constructor, and the value is never assigned again, you don't need to check whether the value is null
; the design of your class has made sure it never can be.
A well-designed object will restrict the opportunities for null
values being assigned and will use guard code where appropriate to throw exceptions when a null
value can be present.