C# 8.0 introduced non-nullable reference types.
Sometimes, however, you want to late initialize a field, like in Kotlin:
lateinit private IConnectionManager _manager;
You can do this in C# using null!
private IConnectionManager _manager = null!;
C# non-nullable references are very useful, but you still need to be disciplined, code defensively, and make good use of guard classes.
Null exceptions are not that hard to avoid. C# avoids a lot of the problems in Java.
I typically use two guard classes in my code:
- Expect – always executes
- Assume – only runs in debug
This distinction allows me to liberally test assumptions knowing they won’t have a runtime hit. Typically public facing methods will use Expect, whilst private methods more often use Assume.
Static analysis tools like Resharper also go along way to helping the developer.
The non-null reference types feature doesn’t help in dynamic situations – that’s where these bugs are really hard to track down. For example, you kick off a new thread in Android, and pass it a reference to the current Activity. The user rotates the screen and the Activity is destroyed and recreated. The thread finishes and calls back the destroyed Activity.
Anything dynamic, initializing at runtime, always has to be handled by the developer. These are the harder issues to manage.
I hope you found the null! tip useful.