Here at endjin, we've recently enabled the new nullable references features in all of our projects. This has led me to a realisation that I often don't think as much as I should about object initialisation patterns. A couple of weeks ago I ran into an issue where I was trying to initalise an object, but the initialisation involved asynchronous operations so couldn't be done in a constructor.
When I first created the class I did this:
Where the asynchronous inititialisation is done via a factory method. However, this means that a
set function is required for the property, and also, when nullable references are enabled you get this warning:
This is because the
AString property is not initialised in the constructor and is therefore technically able to be null. It would be better to be able to make the property truly readonly, and to ensure that it is always initialised as non-null.
To do this we can use the async factory method pattern:
Here we have a constructor which takes a
string, which we use in the initialiser to produce a fully populated object. Also, as the constructor is private we know that the objects can only be initalisated from inside the
Thing class. And, as the constructor takes a non-nullable string, we will get a warning if we try and pass anything that could be null in.
For example, if the
GetStringAsync method returned a nullable string:
Then we would see this warning from the compiler when we try to pass it into the consructor:
This is a simple pattern but one that I think is incredibly useful in avoiding partial instantiation and null reference exceptions!