Why can't NullReferenceException tell you the type of the instance that was null?

If you have done much managed development you have run into a NullReferenceException more times that you’d care to count. The CLR throws this exception when you try to access instance state on null instance…

One of your internal customers suggested we give the type of instance that was null to help track down the errors. Not a bad idea, but Chris Brumme made it clear this is harder than you might expect…

The NullReferenceException occurs because an instruction like “call [eax+44]” or “mov edx, [esi+24]” has resulted in an access violation. We don’t retain nearly enough information to form a correspondence between a particular register being NULL at a particular EIP and the fact that a particular reference in the application was null. Especially since the EIP might be in a shared helper like a write barrier routine or an array helper. In those cases, we would have to perform a limited stack walk to get the effective EIP.

The machinery that would be required to improve this error message is huge. For the foreseeable future, you will have to rely on debuggers, or on FX code explicitly checking and throwing an appropriate NullArgumentException.

Oh well, back to the debugger!

But this does raise a number of interesting questions….

1) I said that we throw a NullReferenceException when you try to access instance “state” (eg a field). What if you have an instance method that does not touch any instance state (for example an instance method that just does a Console.WriteLine (“hello“)). Will you get a NullReferenceException when you call that? Why? Hint: It is one of those interesting differences between the CLR and the C# programming language.

2) As Chris implies above, the .NET Framework and WinFX generally do argument checking on all publicly exposed APIs. I continue to think this is a good thing to help you track to errors, but we do pay a very small perf price for these… Are they worth it?

3) Back in the day we had a number of long debates about the naming of NullReferenceException. As you VB folks know, there is no such this as Null in the VB world (expect maybe in the database)… VB uses the term “Nothing” for this concept. In retrospect should we have called in “NullReferenceOrNothingException”? Has anyone worked with a VB developer that was actually confused by this?

 

rewritting history here a little bit... I put “Empty” instead of “Nothing” when I first posted. Thanks to those of you who pointed it out.