C#创建安全的字典(Dictionary)存储结构

2019-12-30 15:02:13刘景俊

     上面主要是对字典(Dictionary)的一些常用方法进行一个简单的说明。接下来主要阐述如何创建安全的字典(Dictionary)存储结构。有关线程安全的部分,在这里就不再赘述了。


  /// <summary>
  /// 线程安全通用字典
  /// </summary>
  /// <typeparam name="TKey"></typeparam>
  /// <typeparam name="TValue"></typeparam>
  public class TDictionary<TKey, TValue> : IDictionary<TKey, TValue>
  {
    /// <summary>
    /// 锁定字典
    /// </summary>
    private readonly ReaderWriterLockSlim _lockDictionary = new ReaderWriterLockSlim();
    /// <summary>
    ///基本字典
    /// </summary>
    private readonly Dictionary<TKey, TValue> _mDictionary;
    // Variables
    /// <summary>
    /// 初始化字典对象
    /// </summary>
    public TDictionary()
    {
      _mDictionary = new Dictionary<TKey, TValue>();
    }
    /// <summary>
    /// 初始化字典对象
    /// </summary>
    /// <param name="capacity">字典的初始容量</param>
    public TDictionary(int capacity)
    {
      _mDictionary = new Dictionary<TKey, TValue>(capacity);
    }
    /// <summary>
    ///初始化字典对象
    /// </summary>
    /// <param name="comparer">比较器在比较键时使用</param>
    public TDictionary(IEqualityComparer<TKey> comparer)
    {
      _mDictionary = new Dictionary<TKey, TValue>(comparer);
    }
    /// <summary>
    /// 初始化字典对象
    /// </summary>
    /// <param name="dictionary">其键和值被复制到此对象的字典</param>
    public TDictionary(IDictionary<TKey, TValue> dictionary)
    {
      _mDictionary = new Dictionary<TKey, TValue>(dictionary);
    }
    /// <summary>
    ///初始化字典对象
    /// </summary>
    /// <param name="capacity">字典的初始容量</param>
    /// <param name="comparer">比较器在比较键时使用</param>
    public TDictionary(int capacity, IEqualityComparer<TKey> comparer)
    {
      _mDictionary = new Dictionary<TKey, TValue>(capacity, comparer);
    }
    /// <summary>
    /// 初始化字典对象
    /// </summary>
    /// <param name="dictionary">其键和值被复制到此对象的字典</param>
    /// <param name="comparer">比较器在比较键时使用</param>
    public TDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)
    {
      _mDictionary = new Dictionary<TKey, TValue>(dictionary, comparer);
    }
    public TValue GetValueAddIfNotExist(TKey key, Func<TValue> func)
    {
      return _lockDictionary.PerformUsingUpgradeableReadLock(() =>
      {
        TValue rVal;

        // 如果我们有值,得到它并退出
        if (_mDictionary.TryGetValue(key, out rVal))
          return rVal;
        // 没有找到,所以做函数得到的值
        _lockDictionary.PerformUsingWriteLock(() =>
        {
          rVal = func.Invoke();
          // 添加到字典
          _mDictionary.Add(key, rVal);
          return rVal;
        });
        return rVal;
      });
    }
    /// <summary>
    /// 将项目添加到字典
    /// </summary>
    /// <param name="key">添加的关键</param>
    /// <param name="value">要添加的值</param>
    public void Add(TKey key, TValue value)
    {
      _lockDictionary.PerformUsingWriteLock(() => _mDictionary.Add(key, value));
    }
    /// <summary>
    ///将项目添加到字典
    /// </summary>
    /// <param name="item">要添加的键/值</param>
    public void Add(KeyValuePair<TKey, TValue> item)
    {
      var key = item.Key;
      var value = item.Value;
      _lockDictionary.PerformUsingWriteLock(() => _mDictionary.Add(key, value));
    }
    /// <summary>
    /// 如果值不存在,则添加该值。 返回如果值已添加,则为true
    /// </summary>
    /// <param name="key">检查的关键,添加</param>
    /// <param name="value">如果键不存在,则添加的值</param>
    public bool AddIfNotExists(TKey key, TValue value)
    {
      bool rVal = false;
      _lockDictionary.PerformUsingWriteLock(() =>
      {
        // 如果不存在,则添加它
        if (!_mDictionary.ContainsKey(key))
        {
          // 添加该值并设置标志
          _mDictionary.Add(key, value);
          rVal = true;
        }
      });
      return rVal;
    }
    /// <summary>
    /// 如果键不存在,则添加值列表。
    /// </summary>
    /// <param name="keys">要检查的键,添加</param>
    /// <param name="defaultValue">如果键不存在,则添加的值</param>
    public void AddIfNotExists(IEnumerable<TKey> keys, TValue defaultValue)
    {
      _lockDictionary.PerformUsingWriteLock(() =>
      {
        foreach (TKey key in keys)
        {
          // 如果不存在,则添加它
          if (!_mDictionary.ContainsKey(key))
            _mDictionary.Add(key, defaultValue);
        }
      });
    }
    public bool AddIfNotExistsElseUpdate(TKey key, TValue value)
    {
      var rVal = false;
      _lockDictionary.PerformUsingWriteLock(() =>
      {
        // 如果不存在,则添加它
        if (!_mDictionary.ContainsKey(key))
        {
          // 添加该值并设置标志
          _mDictionary.Add(key, value);
          rVal = true;
        }
        else
          _mDictionary[key] = value;
      });
      return rVal;
    }
    /// <summary>
    /// 如果键存在,则更新键的值。
    /// </summary>
    /// <param name="key"></param>
    /// <param name="newValue"></param>
    public bool UpdateValueIfKeyExists(TKey key, TValue newValue)
    {
      bool rVal = false;
      _lockDictionary.PerformUsingWriteLock(() =>
      {
        // 如果我们有密钥,然后更新它
        if (!_mDictionary.ContainsKey(key)) return;
        _mDictionary[key] = newValue;
        rVal = true;
      });
      return rVal;
    }
    /// <summary>
    /// 如果键值对存在于字典中,则返回true
    /// </summary>
    /// <param name="item">键值对查找</param>
    public bool Contains(KeyValuePair<TKey, TValue> item)
    {
      return _lockDictionary.PerformUsingReadLock(() => ((_mDictionary.ContainsKey(item.Key)) &&
                               (_mDictionary.ContainsValue(item.Value))));
    }
    public bool ContainsKey(TKey key)
    {
      return _lockDictionary.PerformUsingReadLock(() => _mDictionary.ContainsKey(key));
    }
    /// <summary>
    /// 如果字典包含此值,则返回true
    /// </summary>
    /// <param name="value">找到的值</param>
    public bool ContainsValue(TValue value)
    {
      return _lockDictionary.PerformUsingReadLock(() => _mDictionary.ContainsValue(value));
    }
    public ICollection<TKey> Keys
    {
      get { return _lockDictionary.PerformUsingReadLock(() => _mDictionary.Keys); }
    }
    public bool Remove(TKey key)
    {
      return _lockDictionary.PerformUsingWriteLock(() => (!_mDictionary.ContainsKey(key)) || _mDictionary.Remove(key));
    }
    public bool Remove(KeyValuePair<TKey, TValue> item)
    {
      return _lockDictionary.PerformUsingWriteLock(() =>
      {
        // 如果键不存在则跳过
        TValue tempVal;
        if (!_mDictionary.TryGetValue(item.Key, out tempVal))
          return false;
        //如果值不匹配,请跳过
        return tempVal.Equals(item.Value) && _mDictionary.Remove(item.Key);
      });
    }
    /// <summary>
    /// 从字典中删除与模式匹配的项
    /// </summary>
    /// <param name="predKey">基于键的可选表达式</param>
    /// <param name="predValue">基于值的选项表达式</param>
    public bool Remove(Predicate<TKey> predKey, Predicate<TValue> predValue)
    {
      return _lockDictionary.PerformUsingWriteLock(() =>
      {
        // 如果没有键退出
        if (_mDictionary.Keys.Count == 0)
          return true;
        //保存要删除的项目列表
        var deleteList = new List<TKey>();
        // 过程密钥
        foreach (var key in _mDictionary.Keys)
        {
          var isMatch = false;
          if (predKey != null)
            isMatch = (predKey(key));
          // 如果此项目的值匹配,请添加它
          if ((!isMatch) && (predValue != null) && (predValue(_mDictionary[key])))
            isMatch = true;
          // 如果我们有匹配,添加到列表
          if (isMatch)
            deleteList.Add(key);
        }
        // 从列表中删除所有项目
        foreach (var item in deleteList)
          _mDictionary.Remove(item);
        return true;
      });
    }
    public bool TryGetValue(TKey key, out TValue value)
    {
      _lockDictionary.EnterReadLock();
      try
      {
        return _mDictionary.TryGetValue(key, out value);
      }
      finally
      {
        _lockDictionary.ExitReadLock();
      }
    }
    public ICollection<TValue> Values
    {
      get { return _lockDictionary.PerformUsingReadLock(() => _mDictionary.Values); }
    }
    public TValue this[TKey key]
    {
      get { return _lockDictionary.PerformUsingReadLock(() => _mDictionary[key]); }
      set { _lockDictionary.PerformUsingWriteLock(() => _mDictionary[key] = value); }
    }
    /// <summary>
    /// 清除字典
    /// </summary>
    public void Clear()
    {
      _lockDictionary.PerformUsingWriteLock(() => _mDictionary.Clear());
    }
    public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
    {
      _lockDictionary.PerformUsingReadLock(() => _mDictionary.ToArray().CopyTo(array, arrayIndex));
    }
    /// <summary>
    /// 返回字典中的项目数
    /// </summary>
    public int Count
    {
      get { return _lockDictionary.PerformUsingReadLock(() => _mDictionary.Count); }
    }
    public bool IsReadOnly
    {
      get { return false; }
    }
    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
    {
      Dictionary<TKey, TValue> localDict = null;
      _lockDictionary.PerformUsingReadLock(() => localDict = new Dictionary<TKey, TValue>(_mDictionary));
      return ((IEnumerable<KeyValuePair<TKey, TValue>>)localDict).GetEnumerator();
    }
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
      Dictionary<TKey, TValue> localDict = null;
      _lockDictionary.PerformUsingReadLock(() => localDict = new Dictionary<TKey, TValue>(_mDictionary));
      return localDict.GetEnumerator();
    }
  }