using System; using System.Collections; using System.Collections.Generic; using System.Linq; namespace IFramework { /// /// 可观测Dictionary /// /// TKey /// TValue public class ObservableDictionary : Unit, IDictionary, IDictionary { #region 事件与变量定义 private Action> onKeyValuePairAdded; private Action, KeyValuePair> onKeyValuePairReplaced; private Action> onKeyValuePairRemoved; private Action onClear; private Action[]> onKeyValuePairRangeAdded; private Lazy> _dictionary = new Lazy>(() => { return new Dictionary(); }); private Dictionary dictionary { get { return _dictionary.Value; } } #endregion #region 注册与移除监听方法 /// /// 注册方法 添加键值对 /// /// /// action arg1 : the Added KeyValuePair of and
/// 参数1为添加的键值对对象,键的类型为,值的类型为 /// public void SubscribeAddKeyValuePair(Action> action) { onKeyValuePairAdded += action; } /// /// 移除方法 添加键值对 /// /// /// action arg1 : the Added KeyValuePair of and
/// 参数1为添加的键值对对象,键的类型为,值的类型为 /// public void UnSubscribeAddKeyValuePair(Action> action) { onKeyValuePairAdded -= action; } /// /// 注册方法 替换键值对 /// /// /// action arg1 : the old KeyValuePair of and which has been replaced
/// 参数1为被替换的键值对对象,键的类型为,值的类型为

/// action arg2 : the new KeyValuePair of and which replaced the old one
/// 参数1为新的键值对对象,键的类型为,值的类型为
/// public void SubscribeReplaceKeyValuePair(Action, KeyValuePair> action) { onKeyValuePairReplaced += action; } /// /// 移除方法 替换键值对 /// /// /// action arg1 : the old KeyValuePair of and which has been replaced
/// 参数1为被替换的键值对对象,键的类型为,值的类型为

/// action arg2 : the new KeyValuePair of and which replaced the old one
/// 参数1为新的键值对对象,键的类型为,值的类型为
/// public void UnSubscribeReplaceKeyValuePair(Action, KeyValuePair> action) { onKeyValuePairReplaced -= action; } /// /// 注册方法 移除键值对 /// /// /// action arg1 : the removed KeyValuePair with and
/// 参数1为移除的键值对对象,键的类型为,值的类型为 /// public void SubscribeRemoveKeyValuePair(Action> action) { onKeyValuePairRemoved += action; } /// /// 移除方法 移除键值对 /// /// /// action arg1 : the removed KeyValuePair with and
/// 参数1为移除的键值对对象,键的类型为,值的类型为 /// public void UnSubscribeRemoveKeyValuePair(Action> action) { onKeyValuePairRemoved -= action; } /// /// 注册方法 清除所有键值对 /// /// none arg Action public void SubscribeClear(Action action) { onClear += action; } /// /// 移除方法 清除所有键值对 /// /// none arg Action public void UnSbscribeClear(Action action) { onClear -= action; } /// /// 注册方法 添加多个键值对 /// /// /// action arg1 : the Added array of KeyValuePair with and
/// 参数1为添加的键值对数组对象,键的类型为,值的类型为 /// public void SubscribeAddRange(Action[]> action) { onKeyValuePairRangeAdded += action; } /// /// 移除方法 添加添加多个键值对 /// /// /// action arg1 : the Added array of KeyValuePair with and
/// 参数1为添加的键值对数组对象,键的类型为,值的类型为 /// public void UnSubscribeAddRange(Action[]> action) { onKeyValuePairRangeAdded -= action; } #endregion #region 接口实现 /// /// 索引器 /// /// 键 /// public TValue this[TKey key] { get { if (!dictionary.ContainsKey(key)) return default(TValue); return dictionary[key]; } set { Insert(key, value, false); } } /// /// 键集合 /// public ICollection Keys { get { return dictionary.Keys; } } /// /// 值集合 /// public ICollection Values { get { return dictionary.Values; } } /// /// 数量 /// public int Count { get { return dictionary.Count; } } /// /// 是否只读 /// public bool IsReadOnly { get { return ((IDictionary)this.dictionary).IsReadOnly; } } /// /// 添加键值对 /// /// 键 /// 值 public void Add(TKey key, TValue value) { Insert(key, value, true); } /// /// 添加键值对 /// /// 键值对 public void Add(KeyValuePair pair) { Insert(pair.Key, pair.Value, true); } /// /// 清除所有键值对 /// public void Clear() { if (dictionary.Count > 0) { dictionary.Clear(); onClear?.Invoke(); } } /// /// 是否存在键值对 /// /// 键值对 /// public bool Contains(KeyValuePair pair) { return dictionary.Contains(pair); } /// /// 是否存在键 /// /// 键 /// 存在情况 public bool ContainsKey(TKey key) { return dictionary.ContainsKey(key); } /// /// 将字典里的键值对拷贝到指定数组中 /// /// 接收的数组 /// 开始保存在数组的索引 public void CopyTo(KeyValuePair[] array, int arrayIndex) { ((IDictionary)this.dictionary).CopyTo(array, arrayIndex); } /// /// 获取迭代器 /// /// 迭代器 public IEnumerator> GetEnumerator() { return dictionary.GetEnumerator(); } /// /// 删除键值对 /// /// 键 /// 是否删除成功 public bool Remove(TKey key) { if (key == null) throw new ArgumentNullException("key is null"); dictionary.TryGetValue(key, out TValue value); var removed = dictionary.Remove(key); if (removed) { onKeyValuePairRemoved.Invoke(new KeyValuePair(key, value)); } return removed; } /// /// 删除键值对 /// /// 键值对 /// 是否删除成功,如果对应的键值对不存在,返回false public bool Remove(KeyValuePair pair) { if (Contains(pair)) { return Remove(pair.Key); } return false; } /// /// 获取指定键对应的值 /// /// 键 /// 保存值的对象 /// 是否获取成功 public bool TryGetValue(TKey key, out TValue value) { return dictionary.TryGetValue(key, out value); } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)dictionary).GetEnumerator(); } object IDictionary.this[object key] { get { return ((IDictionary)this.dictionary)[key]; } set { Insert((TKey)key, (TValue)value, false); } } ICollection IDictionary.Keys { get { return ((IDictionary)this.dictionary).Keys; } } ICollection IDictionary.Values { get { return ((IDictionary)this.dictionary).Values; } } IDictionaryEnumerator IDictionary.GetEnumerator() { return ((IDictionary)this.dictionary).GetEnumerator(); } bool IDictionary.Contains(object key) { return ((IDictionary)this.dictionary).Contains(key); } void IDictionary.Add(object key, object value) { this.Add((TKey)key, (TValue)value); } void IDictionary.Remove(object key) { this.Remove((TKey)key); } bool IDictionary.IsFixedSize { get { return ((IDictionary)this.dictionary).IsFixedSize; } } object ICollection.SyncRoot { get { return ((IDictionary)this.dictionary).SyncRoot; } } bool ICollection.IsSynchronized { get { return ((IDictionary)this.dictionary).IsSynchronized; } } void ICollection.CopyTo(Array array, int index) { ((IDictionary)this.dictionary).CopyTo(array, index); } /// /// 对象释放时调用(继承自Unit) /// protected override void OnDispose() { dictionary.Clear(); onKeyValuePairAdded -= onKeyValuePairAdded; onKeyValuePairReplaced -= onKeyValuePairReplaced; onKeyValuePairRemoved -= onKeyValuePairRemoved; } #endregion #region 额外方法实现 private void Insert(TKey key, TValue value, bool isAdd) { if (key == null) throw new ArgumentNullException("key is null"); if (dictionary.TryGetValue(key, out TValue oldValue)) { if (isAdd) throw new ArgumentException("this key has already been added"); if (Equals(oldValue, value)) return; dictionary[key] = value; onKeyValuePairReplaced?.Invoke(new KeyValuePair(key, oldValue), new KeyValuePair(key, value)); } else { dictionary[key] = value; onKeyValuePairAdded?.Invoke(new KeyValuePair(key, value)); } } /// /// 将一个字典添加到另一个字典中 /// /// 字典对象 public void AddRange(IDictionary items) { if (items == null) throw new ArgumentNullException("items is null"); if (items.Count > 0) { if (items.Keys.Any((k) => this.dictionary.ContainsKey(k))) throw new ArgumentException("a key or some keys in this dictionary has already been added"); else { foreach (var item in items) ((IDictionary)this.dictionary).Add(item); } onKeyValuePairRangeAdded?.Invoke(items.ToArray()); } } #endregion } }