I would like a way to get warnings when an object reference could potentially throw a Null Reference Exception, so that I can write defensive code for these.
I have looked at Resharper, but didn't see anything there that accomplishes this.
Code Contracts is probably a non-starter; the application is quite large, and it's written in .NET 3.5, before Code Contracts became officially available.
Resharper does in fact accomplish something like this. Possible NullReferenceExpections are highlighted in the IDE in blue, with tooltips when you hover over them.
Resharper then keeps track of potential errors and warnings in it's own inspection results window (separate from Visual Studio's compiler errors and warnings).
Generally speaking, unless you specifically initialized an object, It can always have the potential to throw a null object reference, at least as far as the compiler is concerned.
in order for an algorithm to check whether a reference to the object can potentially be null, it would have to traverse every possible path that your program can take, and that includes paths in any external libraries that you may be using. Even for the simplest of programs, such an algorithm would kill the performance of your compiler.
I'm against the idea of blindly defending against null for each field available in the code and inside each method.
The following help me deciding about where to check against null values:
1- Who will be invoking your methods? If a method is private and you have control over how's it's being accessed, I don't see it makes sense to protect against null checks unless it's part of the method's logic to expect null values. If a method is exposed to the public (Such as an API), then of course null checks should be a huge concern.
2- Software Design:
Image you have are calling
method1(fromAnimalToString(animal)); and for some reason
fromAnimalToString() never returns null (Though might return an empty string instead).
Then in such case, it wouldn't make sense to check
animal != null in method1()'s body
3- Testing: In software engineering, it's almost impossible to test all possible scenarios that can ever execute. However, test normal and alternative scenarios and make sure the flow is as expected.