I have some auto-instantiation code which I would like to apply to about 15 properties in a fairly big class. The code is similar to the following but the type is differ
You can use the ??
operator to simplify the code into one line:
protected ComplexType _propertyName;
public ComplexType PropertyName
{
get
{
return _propertyName ?? (_propertyName = new ComplexType());
}
}
As a side note I would probably avoid protected fields. If you need to set the property from a derived class I would rather create a protected setter.
You could implement lazy initialization in a manner similar to this:
public class Lazy<T> where T : new()
{
private T _value;
private bool _isInitialized;
private T GetValue()
{
if (!_isInitialized)
{
_value = new T();
_isInitialized = true;
}
return _value;
}
public static implicit operator T (Lazy<T> t)
{
return t.GetValue();
}
}
which would allow you to write code like this:
private Lazy<ComplexType> _lazyCt = new Lazy<ComplexType>();
public ComplexType LazyCt
{
get { return _lazyCt; }
}
The specifics of the initialization are irrelevant, I wrote it like this to show that you can make it transparently convertible to the non-lazy version, and perform the initialization on the first conversion. :)
You could use the much overlooked T4 (Text Template Transformation Toolkit) to generate the code. It is included with Visual Studio 2008.
There was a 2009-06 .NET Rocks episode about it: "Peter Vogel uses Code Generation".
You can make a generic struct that handles the lazy creation:
public struct LazyCreate<T> where T : class, new() {
private T _value;
public T Value {
get {
if (_value == null) {
_value = new T();
}
return _value;
}
}
}
protected LazyCreate<ComplexType> _propertyName;
public ComplexType PropertyName {
get {
return _propertyName.Value;
}
}
This might make things a bit neater, you could add this method to introduce some reuse:
protected ComplexType _propertyName;
public ComplexType PropertyName
{
get
{
return GetProperty(ref _propertyName);
}
}
.
.
private T GetProperty<T>(ref T property) where T : new()
{
if (property == null)
property = new T();
return property;
}
Even though it doesn't directly solve your problem, you could have a look at the new Lazy<T> class that ships with .NET 4.0. It is specifically designed for lazy initialization scenarios.