I recently had a coding bug where under certain conditions a variable wasn’t being initialized and I was getting a NullReferenceException . This took a while to debug as I had to find the bits of data that would generate this to recreate it the error as the exception doesn’t give the variable name.
Obviously I could check every variable before use and throw an informative exception but is there a better (read less coding) way of doing this? Another thought I had was shipping with the pdb files so that the error information would contain the code line that caused the error. How do other people avoid / handle this problem?
Thanks
Firstly: don’t do too much in a single statement. If you have huge numbers of dereferencing operations in one line, it’s going to be much harder to find the culprit. The Law of Demeter helps with this too – if you’ve got something like
order.SalesClerk.Manager.Address.Street.Lengththen you’ve got a lot of options to wade through when you get an exception. (I’m not dogmatic about the Law of Demeter, but everything in moderation…)Secondly: prefer casting over using
as, unless it’s valid for the object to be a different type, which normally involves a null check immediately afterwards. So here:Here we’d get a NullReferenceException and eventually trace it back to
textbeing null – but then you wouldn’t know whether that’s becausefoowas null, or because it was an unexpected type. If it should really, really be astring, then cast instead:Now you’ll be able to tell the difference between the two scenarios.
Thirdly: as others have said, validate your data – typically arguments to public and potentially internal APIs. I do this in enough places in Noda Time that I’ve got a utility class to help me declutter the check. So for example (from
Period):You should document what can and can’t be null, too.