当前位置: 移动技术网 > IT编程>开发语言>c# > C#创建安全的字典(Dictionary)存储结构

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

2019年07月18日  | 移动技术网IT编程  | 我要评论
在上面介绍过栈(stack)的存储结构,接下来介绍另一种存储结构字典(dictionary)。 字典(dictionary)里面的每一个元素都是一个键值对(由二个元素组成:

在上面介绍过栈(stack)的存储结构,接下来介绍另一种存储结构字典(dictionary)。 字典(dictionary)里面的每一个元素都是一个键值对(由二个元素组成:键和值) 键必须是唯一的,而值不需要唯一的,键和值都可以是任何类型。字典(dictionary)是常用于查找和排序的列表。

  接下来看一下dictionary的部分方法和类的底层实现代码:

  1.add:将指定的键和值添加到字典中。

  public void add(tkey key, tvalue value) {
      insert(key, value, true); 
    }
 private void insert(tkey key, tvalue value, bool add) {
       if( key == null ) { 
        throwhelper.throwargumentnullexception(exceptionargument.key);
      } 
      if (buckets == null) initialize(0);
      int hashcode = comparer.gethashcode(key) & 0x7fffffff;
      int targetbucket = hashcode % buckets.length; 
#if feature_randomized_string_hashing 
      int collisioncount = 0; 
#endif
      for (int i = buckets[targetbucket]; i >= 0; i = entries[i].next) {
        if (entries[i].hashcode == hashcode && comparer.equals(entries[i].key, key)) {
          if (add) {
            throwhelper.throwargumentexception(exceptionresource.argument_addingduplicate); 
          }
          entries[i].value = value; 
          version++; 
          return;
        } 
#if feature_randomized_string_hashing
        collisioncount++;
#endif 
      }
      int index; 
      if (freecount > 0) { 
        index = freelist;
        freelist = entries[index].next; 
        freecount--;
      }
      else {
        if (count == entries.length) 
        {
          resize(); 
          targetbucket = hashcode % buckets.length; 
        }
        index = count; 
        count++;
      }
      entries[index].hashcode = hashcode; 
      entries[index].next = buckets[targetbucket];
      entries[index].key = key; 
      entries[index].value = value; 
      buckets[targetbucket] = index;
      version++; 
#if feature_randomized_string_hashing
      if(collisioncount > hashhelpers.hashcollisionthreshold && hashhelpers.iswellknownequalitycomparer(comparer))
      { 
        comparer = (iequalitycomparer<tkey>) hashhelpers.getrandomizedequalitycomparer(comparer);
        resize(entries.length, true); 
      } 
#endif
    }

  2.clear():从 dictionary<tkey, tvalue> 中移除所有的键和值。

 public void clear() {
      if (count > 0) {
        for (int i = 0; i < buckets.length; i++) buckets[i] = -1;
        array.clear(entries, 0, count); 
        freelist = -1;
        count = 0; 
        freecount = 0; 
        version++;
      } 
    }

   3.remove():从 dictionary<tkey, tvalue> 中移除所指定的键的值。

 public bool remove(tkey key) {
      if(key == null) {
        throwhelper.throwargumentnullexception(exceptionargument.key);
      } 
      if (buckets != null) { 
        int hashcode = comparer.gethashcode(key) & 0x7fffffff; 
        int bucket = hashcode % buckets.length;
        int last = -1; 
        for (int i = buckets[bucket]; i >= 0; last = i, i = entries[i].next) {
          if (entries[i].hashcode == hashcode && comparer.equals(entries[i].key, key)) {
            if (last < 0) {
              buckets[bucket] = entries[i].next; 
            }
            else { 
              entries[last].next = entries[i].next; 
            }
            entries[i].hashcode = -1; 
            entries[i].next = freelist;
            entries[i].key = default(tkey);
            entries[i].value = default(tvalue);
            freelist = i; 
            freecount++;
            version++; 
            return true; 
          }
        } 
      }
      return false;
    }

  4.getenumerator():返回循环访问 dictionary<tkey, tvalue> 的枚举器。

  public enumerator getenumerator() {
      return new enumerator(this, enumerator.keyvaluepair); 
    }
 [serializable] 
    public struct enumerator: ienumerator<keyvaluepair<tkey,tvalue>>,
      idictionaryenumerator 
    { 
      private dictionary<tkey,tvalue> dictionary;
      private int version; 
      private int index;
      private keyvaluepair<tkey,tvalue> current;
      private int getenumeratorrettype; // what should enumerator.current return?
      internal const int dictentry = 1;
      internal const int keyvaluepair = 2; 
      internal enumerator(dictionary<tkey,tvalue> dictionary, int getenumeratorrettype) {
        this.dictionary = dictionary; 
        version = dictionary.version;
        index = 0;
        this.getenumeratorrettype = getenumeratorrettype;
        current = new keyvaluepair<tkey, tvalue>(); 
      }
      public bool movenext() { 
        if (version != dictionary.version) {
          throwhelper.throwinvalidoperationexception(exceptionresource.invalidoperation_enumfailedversion); 
        }
        // use unsigned comparison since we set index to dictionary.count+1 when the enumeration ends.
        // dictionary.count+1 could be negative if dictionary.count is int32.maxvalue 
        while ((uint)index < (uint)dictionary.count) {
          if (dictionary.entries[index].hashcode >= 0) { 
            current = new keyvaluepair<tkey, tvalue>(dictionary.entries[index].key, dictionary.entries[index].value); 
            index++;
            return true; 
          }
          index++;
        }
        index = dictionary.count + 1;
        current = new keyvaluepair<tkey, tvalue>(); 
        return false; 
      }
      public keyvaluepair<tkey,tvalue> current {
        get { return current; }
      }
      public void dispose() {
      } 
      object ienumerator.current {
        get { 
          if( index == 0 || (index == dictionary.count + 1)) {
            throwhelper.throwinvalidoperationexception(exceptionresource.invalidoperation_enumopcanthappen);
          }
          if (getenumeratorrettype == dictentry) {
            return new system.collections.dictionaryentry(current.key, current.value); 
          } else { 
            return new keyvaluepair<tkey, tvalue>(current.key, current.value);
          } 
        }
      }
      void ienumerator.reset() { 
        if (version != dictionary.version) {
          throwhelper.throwinvalidoperationexception(exceptionresource.invalidoperation_enumfailedversion); 
        } 
        index = 0; 
        current = new keyvaluepair<tkey, tvalue>();
      }
      dictionaryentry idictionaryenumerator.entry { 
        get {
          if( index == 0 || (index == dictionary.count + 1)) { 
             throwhelper.throwinvalidoperationexception(exceptionresource.invalidoperation_enumopcanthappen); 
          }
          return new dictionaryentry(current.key, current.value);
        }
      }
      object idictionaryenumerator.key {
        get { 
          if( index == 0 || (index == dictionary.count + 1)) { 
             throwhelper.throwinvalidoperationexception(exceptionresource.invalidoperation_enumopcanthappen);
          } 
          return current.key;
        }
      } 
      object idictionaryenumerator.value { 
        get { 
          if( index == 0 || (index == dictionary.count + 1)) {
             throwhelper.throwinvalidoperationexception(exceptionresource.invalidoperation_enumopcanthappen); 
          }
          return current.value;
        } 
      }
    }

     上面主要是对字典(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();
    }
  }

    以上创建安全的字典方法中,主要对字典的一些方法和属性进行重写操作,对某些方法进行锁设置。

    以上就是本文的全部内容,希望对大家有所帮助,同时也希望多多支持移动技术网!

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网