1
+ using System ;
2
+ using System . Collections ;
3
+ using System . Collections . Generic ;
4
+
5
+ namespace CodingMilitia . MoarCollections . Dictionaries
6
+ {
7
+ /// <summary>
8
+ /// <para>
9
+ /// Acts as a wrapper over a <see cref="Dictionary{TKey, TValue}"/> with the ability of returning a default value (static or using a <see cref="Func{TKey, TValue}"/>)
10
+ /// when the requested key is not present.
11
+ /// </para>
12
+ /// <para>
13
+ /// Most of the times, using <see cref="IDictionary{TKey, TValue}.TryGetValue(TKey, out TValue)"/> on a regular Dictionary will be good enough,
14
+ /// this should only be useful when you just want to index and forget.
15
+ /// </para>
16
+ /// <para>The <see cref="Func{TKey, TValue}"/> can be also useful in cases we want to throw a specific exception when the key is not found.</para>
17
+ /// </summary>
18
+ /// <typeparam name="TKey"></typeparam>
19
+ /// <typeparam name="TValue"></typeparam>
20
+ public class DictionaryWithDefaultValue < TKey , TValue > : IDictionary < TKey , TValue >
21
+ {
22
+ private readonly Dictionary < TKey , TValue > _backingDictionary ;
23
+ private readonly TValue _defaultValue ;
24
+ private readonly Func < TKey , TValue > _defaultValueFunc ;
25
+
26
+ public DictionaryWithDefaultValue ( TValue defaultValue )
27
+ {
28
+ _backingDictionary = new Dictionary < TKey , TValue > ( ) ;
29
+ _defaultValue = defaultValue ;
30
+ _defaultValueFunc = null ;
31
+ }
32
+
33
+ public DictionaryWithDefaultValue ( IDictionary < TKey , TValue > sourceDictionary , TValue defaultValue )
34
+ {
35
+ _backingDictionary = sourceDictionary != null ? new Dictionary < TKey , TValue > ( sourceDictionary ) : throw new ArgumentNullException ( nameof ( sourceDictionary ) ) ;
36
+ _defaultValue = defaultValue ;
37
+ _defaultValueFunc = null ;
38
+ }
39
+
40
+ public DictionaryWithDefaultValue ( Func < TKey , TValue > defaultValueFunc )
41
+ {
42
+ _backingDictionary = new Dictionary < TKey , TValue > ( ) ;
43
+ _defaultValue = default ( TValue ) ;
44
+ _defaultValueFunc = defaultValueFunc ?? throw new ArgumentNullException ( nameof ( defaultValueFunc ) ) ;
45
+ }
46
+
47
+ public DictionaryWithDefaultValue ( IDictionary < TKey , TValue > sourceDictionary , Func < TKey , TValue > defaultValueFunc )
48
+ {
49
+ _backingDictionary = sourceDictionary != null ? new Dictionary < TKey , TValue > ( sourceDictionary ) : throw new ArgumentNullException ( nameof ( sourceDictionary ) ) ;
50
+ _defaultValue = default ( TValue ) ;
51
+ _defaultValueFunc = defaultValueFunc ?? throw new ArgumentNullException ( nameof ( defaultValueFunc ) ) ;
52
+ }
53
+
54
+ public TValue this [ TKey key ]
55
+ {
56
+ get => _backingDictionary . TryGetValue ( key , out var value ) ? value : _defaultValueFunc != null ? _defaultValueFunc ( key ) : _defaultValue ;
57
+ set => _backingDictionary [ key ] = value ;
58
+ }
59
+
60
+ public ICollection < TKey > Keys => _backingDictionary . Keys ;
61
+
62
+ public ICollection < TValue > Values => _backingDictionary . Values ;
63
+
64
+ public int Count => _backingDictionary . Count ;
65
+
66
+ public bool IsReadOnly => ( ( IDictionary < TKey , TValue > ) _backingDictionary ) . IsReadOnly ;
67
+
68
+ public void Add ( TKey key , TValue value ) => _backingDictionary . Add ( key , value ) ;
69
+
70
+ public void Add ( KeyValuePair < TKey , TValue > item ) => ( ( IDictionary < TKey , TValue > ) _backingDictionary ) . Add ( item ) ;
71
+
72
+ public void Clear ( ) => _backingDictionary . Clear ( ) ;
73
+
74
+ public bool Contains ( KeyValuePair < TKey , TValue > item ) => ( ( IDictionary < TKey , TValue > ) _backingDictionary ) . Contains ( item ) ;
75
+
76
+ public bool ContainsKey ( TKey key ) => _backingDictionary . ContainsKey ( key ) ;
77
+
78
+ public void CopyTo ( KeyValuePair < TKey , TValue > [ ] array , int arrayIndex ) => ( ( IDictionary < TKey , TValue > ) _backingDictionary ) . CopyTo ( array , arrayIndex ) ;
79
+
80
+ public IEnumerator < KeyValuePair < TKey , TValue > > GetEnumerator ( ) => _backingDictionary . GetEnumerator ( ) ;
81
+
82
+ public bool Remove ( TKey key ) => _backingDictionary . Remove ( key ) ;
83
+
84
+ public bool Remove ( KeyValuePair < TKey , TValue > item ) => ( ( IDictionary < TKey , TValue > ) _backingDictionary ) . Remove ( item ) ;
85
+
86
+ public bool TryGetValue ( TKey key , out TValue value ) => _backingDictionary . TryGetValue ( key , out value ) ;
87
+
88
+ IEnumerator IEnumerable . GetEnumerator ( ) => GetEnumerator ( ) ;
89
+ }
90
+ }
0 commit comments