NullableDictionary.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. namespace Masuit.Tools.Systems;
  6. /// <summary>
  7. /// 支持null-key和value的字典类型
  8. /// </summary>
  9. /// <typeparam name="TKey"></typeparam>
  10. /// <typeparam name="TValue"></typeparam>
  11. public class NullableDictionary<TKey, TValue> : Dictionary<NullObject<TKey>, TValue>
  12. {
  13. public NullableDictionary()
  14. {
  15. }
  16. public NullableDictionary(TValue fallbackValue)
  17. {
  18. FallbackValue = fallbackValue;
  19. }
  20. public NullableDictionary(int capacity) : base(capacity)
  21. {
  22. }
  23. public NullableDictionary(IEqualityComparer<NullObject<TKey>> comparer) : base(comparer)
  24. {
  25. }
  26. public NullableDictionary(int capacity, IEqualityComparer<NullObject<TKey>> comparer) : base(capacity, comparer)
  27. {
  28. }
  29. public NullableDictionary(IDictionary<NullObject<TKey>, TValue> dictionary) : base(dictionary)
  30. {
  31. }
  32. public NullableDictionary(IDictionary<NullObject<TKey>, TValue> dictionary, IEqualityComparer<NullObject<TKey>> comparer) : base(dictionary, comparer)
  33. {
  34. }
  35. internal TValue FallbackValue { get; set; }
  36. /// <summary>
  37. ///
  38. /// </summary>
  39. /// <param name="key"></param>
  40. public new TValue this[NullObject<TKey> key]
  41. {
  42. get => TryGetValue(key, out var value) ? value : FallbackValue;
  43. set => base[key] = value;
  44. }
  45. public virtual TValue this[Func<KeyValuePair<TKey, TValue>, bool> condition]
  46. {
  47. get
  48. {
  49. foreach (var pair in this.Where(pair => condition(new KeyValuePair<TKey, TValue>(pair.Key.Item, pair.Value))))
  50. {
  51. return pair.Value;
  52. }
  53. return FallbackValue;
  54. }
  55. set
  56. {
  57. foreach (var pair in this.Where(pair => condition(new KeyValuePair<TKey, TValue>(pair.Key.Item, pair.Value))))
  58. {
  59. this[pair.Key] = value;
  60. }
  61. }
  62. }
  63. public virtual TValue this[Func<TKey, TValue, bool> condition]
  64. {
  65. get
  66. {
  67. foreach (var pair in this.Where(pair => condition(pair.Key.Item, pair.Value)))
  68. {
  69. return pair.Value;
  70. }
  71. return FallbackValue;
  72. }
  73. set
  74. {
  75. foreach (var pair in this.Where(pair => condition(pair.Key.Item, pair.Value)))
  76. {
  77. this[pair.Key] = value;
  78. }
  79. }
  80. }
  81. public virtual TValue this[Func<TKey, bool> condition]
  82. {
  83. get
  84. {
  85. foreach (var pair in this.Where(pair => condition(pair.Key.Item)))
  86. {
  87. return pair.Value;
  88. }
  89. return FallbackValue;
  90. }
  91. set
  92. {
  93. foreach (var pair in this.Where(pair => condition(pair.Key.Item)))
  94. {
  95. this[pair.Key] = value;
  96. }
  97. }
  98. }
  99. public virtual TValue this[Func<TValue, bool> condition]
  100. {
  101. get
  102. {
  103. foreach (var pair in this.Where(pair => condition(pair.Value)))
  104. {
  105. return pair.Value;
  106. }
  107. return FallbackValue;
  108. }
  109. set
  110. {
  111. foreach (var pair in this.Where(pair => condition(pair.Value)))
  112. {
  113. this[pair.Key] = value;
  114. }
  115. }
  116. }
  117. /// <summary>
  118. ///
  119. /// </summary>
  120. /// <param name="key"></param>
  121. public virtual TValue this[TKey key]
  122. {
  123. get => TryGetValue(new NullObject<TKey>(key), out var value) ? value : FallbackValue;
  124. set => base[new NullObject<TKey>(key)] = value;
  125. }
  126. public bool ContainsKey(TKey key)
  127. {
  128. return base.ContainsKey(new NullObject<TKey>(key));
  129. }
  130. public void Add(TKey key, TValue value)
  131. {
  132. base.Add(new NullObject<TKey>(key), value);
  133. }
  134. public bool Remove(TKey key)
  135. {
  136. return base.Remove(new NullObject<TKey>(key));
  137. }
  138. public bool TryGetValue(TKey key, out TValue value)
  139. {
  140. return base.TryGetValue(new NullObject<TKey>(key), out value);
  141. }
  142. /// <summary>
  143. /// 隐式转换
  144. /// </summary>
  145. /// <param name="dic"></param>
  146. public static implicit operator NullableDictionary<TKey, TValue>(Dictionary<TKey, TValue> dic)
  147. {
  148. var nullableDictionary = new NullableDictionary<TKey, TValue>();
  149. foreach (var p in dic)
  150. {
  151. nullableDictionary[p.Key] = p.Value;
  152. }
  153. return nullableDictionary;
  154. }
  155. /// <summary>
  156. /// 隐式转换
  157. /// </summary>
  158. /// <param name="dic"></param>
  159. public static implicit operator NullableDictionary<TKey, TValue>(ConcurrentDictionary<TKey, TValue> dic)
  160. {
  161. var nullableDictionary = new NullableDictionary<TKey, TValue>();
  162. foreach (var p in dic)
  163. {
  164. nullableDictionary[p.Key] = p.Value;
  165. }
  166. return nullableDictionary;
  167. }
  168. /// <summary>
  169. /// 隐式转换
  170. /// </summary>
  171. /// <param name="dic"></param>
  172. public static implicit operator Dictionary<TKey, TValue>(NullableDictionary<TKey, TValue> dic)
  173. {
  174. var newdic = new Dictionary<TKey, TValue>();
  175. foreach (var p in dic)
  176. {
  177. newdic[p.Key] = p.Value;
  178. }
  179. return newdic;
  180. }
  181. }