A lazy object is an object that is not initialized when the application runs, but when it’s first needed. This improves the overall performance of the application and ensures that the memory is not misused.
One basic approach is to use the classical construct:
private static Settings settings; public static Settings Settings { get { if (settings == null) { mutex.WaitOne(); if (settings == null) { settings = new Settings(); } mutex.ReleaseMutex(); } return settings; } }}
This approach actually works for me and I have used it many times. The thing that I hate about it is having to write all these lines over and over again.
One solution would the the Lazy<T> class:
public static Lazy Settings { get; } = new Lazy(LazyThreadSafetyMode.ExecutionAndPublication); private static void Main(string[] args) { Console.WriteLine(Settings.Value); }
Looks better. But I wouldn’t like a class with all properties Lazy (well, at least not so obvious). I think that a property should reflect the actual type and it should not be a wrapper over the actual type. So my solution for this is something that uses the code construct for the late binding and it has an implicit conversion to the actual wrapped type:
public class Late<T> where T : class { private T _value; private static readonly Mutex mutex = new Mutex(); public T Value { get { if (_value == null) { mutex.WaitOne(); //test again - the value may have been initialized while lock was being set if (_value == null) { _value = _factory(); } mutex.ReleaseMutex(); } return _value; } set { _value = value; } } public Func<T> _factory; public Late(Func<T> factory) { _factory = factory; } public static implicit operator T(Late<T> me) { return me.Value; } }
With this approach, we have the Settings property, that is actually the Late wrapper over the Settings type.
public static Settings Settings { get; } = new Late(()=>new Settings()); private static void Main(string[] args) { Console.WriteLine(Settings.Option1); }