using System;
using System.Collections;
using System.Collections.Generic;
public class DefaultDictionary<TKey, TValue>: IDictionary<TKey, TValue>, IReadOnlyDictionary<TKey, TValue>
{
private readonly Dictionary<TKey, TValue> _dictionary;
public Func<TKey, TValue> ValueFactory { get; }
#region Factory constructors
public DefaultDictionary(Func<TKey, TValue> valueFactory)
{
if (valueFactory == null) throw new ArgumentNullException(nameof(valueFactory));
ValueFactory = valueFactory;
}
public DefaultDictionary(IDictionary<TKey, TValue> dictionary, Func<TKey, TValue> valueFactory)
{
if (valueFactory == null) throw new ArgumentNullException(nameof(valueFactory));
_dictionary = new Dictionary<TKey, TValue>(dictionary);
ValueFactory = valueFactory;
}
public DefaultDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer, Func<TKey, TValue> valueFactory)
{
if (valueFactory == null) throw new ArgumentNullException(nameof(valueFactory));
_dictionary = new Dictionary<TKey, TValue>(dictionary, comparer);
ValueFactory = valueFactory;
}
public DefaultDictionary(IEqualityComparer<TKey> comparer, Func<TKey, TValue> valueFactory)
{
if (valueFactory == null) throw new ArgumentNullException(nameof(valueFactory));
_dictionary = new Dictionary<TKey, TValue>(comparer);
ValueFactory = valueFactory;
}
public DefaultDictionary(int capacity, Func<TKey, TValue> valueFactory)
{
if (valueFactory == null) throw new ArgumentNullException(nameof(valueFactory));
_dictionary = new Dictionary<TKey, TValue>(capacity);
ValueFactory = valueFactory;
}
public DefaultDictionary(int capacity, IEqualityComparer<TKey> comparer, Func<TKey, TValue> valueFactory)
{
if (valueFactory == null) throw new ArgumentNullException(nameof(valueFactory));
_dictionary = new Dictionary<TKey, TValue>(capacity, comparer);
ValueFactory = valueFactory;
}
#endregion
#region Value constructors
public DefaultDictionary(TValue value): this(_ => value) { }
public DefaultDictionary(IDictionary<TKey, TValue> dictionary, TValue value): this(dictionary, _ => value) { }
public DefaultDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer, TValue value): this(dictionary, comparer,
_ => value) { }
public DefaultDictionary(IEqualityComparer<TKey> comparer, TValue value): this(comparer, _ => value) { }
public DefaultDictionary(int capacity, TValue value): this(capacity, _ => value) { }
public DefaultDictionary(int capacity, IEqualityComparer<TKey> comparer, TValue value): this(capacity, comparer, _ => value) { }
#endregion
#region Dictionary constructors
public DefaultDictionary(): this(default(TValue)) { }
public DefaultDictionary(IDictionary<TKey, TValue> dictionary): this(dictionary, default(TValue)) { }
public DefaultDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer):
this(dictionary, comparer, default(TValue)) { }
public DefaultDictionary(IEqualityComparer<TKey> comparer): this(comparer, default(TValue)) { }
public DefaultDictionary(int capacity): this(capacity, default(TValue)) { }
public DefaultDictionary(int capacity, IEqualityComparer<TKey> comparer): this(capacity, comparer, default(TValue)) { }
#endregion
#region Implementation of IEnumerable
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
return _dictionary.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable) _dictionary).GetEnumerator();
}
#endregion
#region Implementation of ICollection<KeyValuePair<TKey,TValue>>
public void Add(KeyValuePair<TKey, TValue> item)
{
((ICollection<KeyValuePair<TKey, TValue>>) _dictionary).Add(item);
}
public void Clear()
{
((ICollection<KeyValuePair<TKey, TValue>>) _dictionary).Clear();
}
public bool Contains(KeyValuePair<TKey, TValue> item)
{
return ((ICollection<KeyValuePair<TKey, TValue>>) _dictionary).Contains(item);
}
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
((ICollection<KeyValuePair<TKey, TValue>>) _dictionary).CopyTo(array, arrayIndex);
}
public bool Remove(KeyValuePair<TKey, TValue> item)
{
return ((ICollection<KeyValuePair<TKey, TValue>>) _dictionary).Remove(item);
}
public int Count => ((ICollection<KeyValuePair<TKey, TValue>>) _dictionary).Count;
public bool IsReadOnly => ((ICollection<KeyValuePair<TKey, TValue>>) _dictionary).IsReadOnly;
#endregion
#region Implementation of IDictionary<TKey,TValue>
public void Add(TKey key, TValue value)
{
_dictionary.Add(key, value);
}
public bool ContainsKey(TKey key)
{
return _dictionary.ContainsKey(key);
}
public bool Remove(TKey key)
{
return _dictionary.Remove(key);
}
public bool TryGetValue(TKey key, out TValue value)
{
if (_dictionary.TryGetValue(key, out value)) return true;
value = ValueFactory(key);
return false;
}
public TValue this[TKey key]
{
get
{
TValue value;
TryGetValue(key, out value);
return value;
}
set { _dictionary[key] = value; }
}
IEnumerable<TKey> IReadOnlyDictionary<TKey, TValue>.Keys => _dictionary.Keys;
IEnumerable<TValue> IReadOnlyDictionary<TKey, TValue>.Values => _dictionary.Values;
public ICollection<TKey> Keys => _dictionary.Keys;
public ICollection<TValue> Values => _dictionary.Values;
#endregion
}