using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; namespace Masuit.Tools.Systems; /// /// 支持null-key和value的字典类型 /// /// /// public class NullableConcurrentDictionary : ConcurrentDictionary, TValue> { public NullableConcurrentDictionary() : base() { } public NullableConcurrentDictionary(TValue fallbackValue) : base() { FallbackValue = fallbackValue; } public NullableConcurrentDictionary(int concurrencyLevel, int capacity) : base(concurrencyLevel, capacity) { } public NullableConcurrentDictionary(IEqualityComparer> comparer) : base(comparer) { } internal TValue FallbackValue { get; set; } public new TValue this[NullObject key] { get => TryGetValue(key, out var value) ? value : FallbackValue; set => base[key] = value; } public TValue this[Func, bool> condition] { get { foreach (var pair in this.Where(pair => condition(new KeyValuePair(pair.Key.Item, pair.Value)))) { return pair.Value; } return FallbackValue; } set { foreach (var pair in this.Where(pair => condition(new KeyValuePair(pair.Key.Item, pair.Value)))) { this[pair.Key] = value; } } } public virtual TValue this[Func condition] { get { foreach (var pair in this.Where(pair => condition(pair.Key.Item, pair.Value))) { return pair.Value; } return FallbackValue; } set { foreach (var pair in this.Where(pair => condition(pair.Key.Item, pair.Value))) { this[pair.Key] = value; } } } public virtual TValue this[Func condition] { get { foreach (var pair in this.Where(pair => condition(pair.Key.Item))) { return pair.Value; } return FallbackValue; } set { foreach (var pair in this.Where(pair => condition(pair.Key.Item))) { this[pair.Key] = value; } } } public virtual TValue this[Func condition] { get { foreach (var pair in this.Where(pair => condition(pair.Value))) { return pair.Value; } return FallbackValue; } set { foreach (var pair in this.Where(pair => condition(pair.Value))) { this[pair.Key] = value; } } } /// /// /// /// public virtual TValue this[TKey key] { get => base.TryGetValue(new NullObject(key), out var value) ? value : FallbackValue; set => base[new NullObject(key)] = value; } public bool ContainsKey(TKey key) { return base.ContainsKey(new NullObject(key)); } public bool TryAdd(TKey key, TValue value) { return base.TryAdd(new NullObject(key), value); } public bool TryRemove(TKey key, out TValue value) { return base.TryRemove(new NullObject(key), out value); } public bool TryUpdate(TKey key, TValue value, TValue comparisionValue) { return base.TryUpdate(new NullObject(key), value, comparisionValue); } public bool TryGetValue(TKey key, out TValue value) { return base.TryGetValue(new NullObject(key), out value); } /// /// 隐式转换 /// /// public static implicit operator NullableConcurrentDictionary(Dictionary dic) { var nullableDictionary = new NullableConcurrentDictionary(); foreach (var p in dic) { nullableDictionary[p.Key] = p.Value; } return nullableDictionary; } /// /// 隐式转换 /// /// public static implicit operator NullableConcurrentDictionary(ConcurrentDictionary dic) { var nullableDictionary = new NullableConcurrentDictionary(); foreach (var p in dic) { nullableDictionary[p.Key] = p.Value; } return nullableDictionary; } /// /// 隐式转换 /// /// public static implicit operator ConcurrentDictionary(NullableConcurrentDictionary dic) { var newdic = new ConcurrentDictionary(); foreach (var p in dic) { newdic[p.Key] = p.Value; } return newdic; } }