using System;
using System.Collections.Generic;
namespace DTT.Utils.Optimization
{
///
/// A dictionary variant that allows for constructors to be added to
/// delay the initial creation of a class to when it is needed.
///
/// The type of key.
/// The type of the value.
public class LazyDictionary : LazyDictionaryBase where TValue : class
{
///
/// Wraps the item value and its constructor, providing
/// a one time initialization upon retrieval.
///
private class Container
{
///
/// The cached item value.
///
private TValue _value;
///
/// The constructor with which to initialize the value.
///
private readonly Func _constructor;
///
/// The accessor to the cached item value.
///
public TValue Value => _value ?? (_value = _constructor());
///
/// Creates a new instance, storing the given constructor.
///
/// The constructor with which to initialize the value.
public Container(Func constructor) => _constructor = constructor;
}
///
/// Contains the keys with their value in their respective containers.
///
private readonly Dictionary _values = new Dictionary();
///
/// Adds a new item to the dictionary with its respective constructor.
///
/// The key for the value.
///
/// The constructor with which to initialize the value.
///
public void Add(TKey key, Func constructor)
{
if (key == null)
throw new ArgumentNullException(nameof(key));
if (constructor == null)
throw new ArgumentNullException(nameof(constructor));
_values.Add(key, new Container(constructor));
}
///
/// Should return the item value based on the given key.
///
/// The key to get the value for.
/// The item value.
protected override TValue GetValue(TKey key) => _values[key].Value;
}
}