C # Create a secure Dictionary (Dictionary) storage structure _c# Tutorial

Source: Internet
Author: User

This article describes the storage structure of the stack (stack), followed by another storage structure dictionary (Dictionary). Every element in the dictionary (Dictionary) is a key value pair (consisting of two elements: key and value) The key must be unique, and the value does not need to be unique, and the key and value can be of any type. A dictionary (Dictionary) is a list that is commonly used to find and sort.

Next, take a look at some of dictionary's methods and the underlying implementation code of the class:

1.ADD: Adds the specified key and value to the dictionary.

  public void Add (TKey key, TValue value) {Insert (key, value, true); private void Insert (TKey key, TValue value, bool add) {if (key = = null) {THROWHELPER.THROWARGUMENTNU
      Llexception (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 = = Hash Code && comparer. Equals (Entries[i].key, key)) {if (add) {throwhelper.throwargumentexception (Exceptionresource.argum 
          Ent_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 && HashHelpe Rs. Iswellknownequalitycomparer (comparer)) {comparer = (iequalitycomparer<tkey>) Hashhelpers.getrandomiz
        Edequalitycomparer (comparer); Resize (entries. 
      Length, True); } #endif}

2.Clear (): Removes all keys and values from 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 (): Removes the value of the specified key from 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 &A mp;& 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 (): Returns an enumerator that iterates through Dictionary<tkey, tvalue>.

  Public enumerator GetEnumerator () {Return to New enumerator (this, enumerator.keyvaluepair); [Serializable] public struct enumerator:ienumerator<keyvaluepair<tkey,tvalue>>, idictionaryenum
      Erator {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 = Dictio 
        nary;
        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 are int32.maxvalue while (UINT) index < (UINT) Dicti Onary.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} 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. Key, current. 
          Value); else {return new Keyvaluepair<tkey, tvalue>. 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 to new DictionaryEntry (current. Key, current.
        Value);
}
      }      Object Idictionaryenumerator.key {get {if (index = = 0 | | (Index = = dictionary.count + 1))
          {throwhelper.throwinvalidoperationexception (Exceptionresource.invalidoperation_enumopcanthappen); Return to current.
        Key; } object Idictionaryenumerator.value {get {if (index = = 0 | | (Index = = dictionary.count + 1)) 
          {throwhelper.throwinvalidoperationexception (Exceptionresource.invalidoperation_enumopcanthappen); Return to current.
        Value; } 
      }
    }

The

     above is primarily a simple description of some common methods of the dictionary (Dictionary). The next major step is to create a secure dictionary (Dictionary) storage structure. The part about thread safety is no longer discussed here.

  <summary>///Thread Safety general dictionary///</summary>///<typeparam name= "TKey" ></typeparam>///& Lt;typeparam name= "TValue" ></typeparam> public class Tdictionary<tkey, tvalue>: Idictionary<tkey, tvalue> {///<summary>///lock dictionary///</summary> private readonly ReaderWriterLockSlim-_lo
    Ckdictionary = new ReaderWriterLockSlim (); 
    <summary>///Basic Dictionary///</summary> private readonly dictionary<tkey, tvalue> _mdictionary; Variables///<summary>///Initialization Dictionary object///</summary> public tdictionary () {_m
    Dictionary = new Dictionary<tkey, tvalue> (); ///<summary>///Initialization Dictionary object///</summary>///<param name= "Capacity" > Dictionary initial capacity </param&
    Gt
    public tdictionary (int capacity) {_mdictionary = new Dictionary<tkey, tvalue> (capacity); ///<summary>///Initialization Dictionary object///&Lt;/summary>///<param name= "Comparer" > Comparer uses </param> public tdictionary when comparing keys (iequalitycomparer<t
    Key> comparer) {_mdictionary = new Dictionary<tkey, tvalue> (comparer); ///<summary>///Initialization Dictionary object///</summary>///<param name= "dictionary" > its keys and values are copied to this object's dictionary &L T;/param> Public Tdictionary (Idictionary<tkey, tvalue> dictionary) {_mdictionary = new dictionary& Lt
    TKey, tvalue> (dictionary); ///<summary>///Initialization Dictionary object///</summary>///<param name= "Capacity" > Dictionary initial capacity &LT;/PARAM&G
    T <param name= the "comparer" > Comparer uses </param> public tdictionary when comparing keys (int capacity, Iequalitycomparer<tkey
    > Comparer) {_mdictionary = new Dictionary<tkey, tvalue> (capacity, comparer); ///<summary>///Initialization Dictionary object///</summary>///<param name= "dictionary" > its keys and values are copied to this object's dictionary &L T;/param>///<paraThe M name= "comparer" > Comparer uses </param> public tdictionary when comparing keys (Idictionary<tkey, Tvalue> dictionary, Iequalitycomparer<tkey> comparer) {_mdictionary = new Dictionary<tkey, tvalue> (Dictionary, comparer
    ); Public TValue getvalueaddifnotexist (TKey key, func<tvalue> Func) {return _lockdictionary.performusi

        Ngupgradeablereadlock (() => {TValue rval;
        If we have a value, get it and exit if (_mdictionary.trygetvalue (key, out Rval)) return rval; Not found, so do function to get the value _lockdictionary.performusingwritelock (() => {rval = func.
          Invoke ();
          Add to Dictionary _mdictionary.add (key, Rval);
        return rval;
        });
      return rval;
    });
    ///<summary>///adds the project to the dictionary///</summary>///<param name= "key" > Added key </param> <param name= "value" > Values to add </param> public void Add (TKey key, TValue value) {
      _lockdictionary.performusingwritelock (() => _mdictionary.add (key, value));
    ///<summary>///Add items to dictionary///</summary>///<param name= "item" > key/value </param> to add public void Add (Keyvaluepair<tkey, tvalue> item) {var key = Item.
      Key; var value = Item.
      Value;
    _lockdictionary.performusingwritelock (() => _mdictionary.add (key, value)); ///<summary>///If the value does not exist, add the value. Returns True///</summary>///<param name= key for check, add </param>///<param name= "va if value is added
      Lue > If the key does not exist, the value added </param> public bool Addifnotexists (TKey key, TValue value) {bool Rval = false; _lockdictionary.performusingwritelock (() => {//If not present, add it if (!_mdictionary.containskey ke
          Y)) {//Add the value and set the flag _mdictionary.add (key, value);
        Rval = true;
      }
      });
    return rval; }///&LT;SUMMARY&GT
    If the key does not exist, add a list of values. </summary>///<param name= "keys" > Keys to check, add </param>///<param name= "DefaultValue" > if the key is not exists, the value added </param> public void addifnotexists (ienumerable<tkey> keys, TValue defaultvalue) {_lock
          Dictionary.performusingwritelock (() => {foreach (TKey key in keys) {//If not present, add it
        if (!_mdictionary.containskey (key)) _mdictionary.add (key, DefaultValue);
    }
      });
      public bool Addifnotexistselseupdate (TKey key, TValue value) {var rval = false;
        _lockdictionary.performusingwritelock (() => {//If not present, add it if (!_mdictionary.containskey (key))
          {//Add the value and set the flag _mdictionary.add (key, value);
        Rval = true;
      else _mdictionary[key] = value;
      });
    return rval;
    ///<summary>///If the key exists, the value of the key is updated.
  </summary>  <param name= "key" ></param>///<param name= "newvalue" ></param> public bool Updateval
      Ueifkeyexists (TKey key, TValue newvalue) {bool Rval = false; _lockdictionary.performusingwritelock (() => {//If we have the key, then update it if (!_mdictionary.containskey (key)
        ) return;
        _mdictionary[key] = newvalue;
      Rval = true;
      });
    return rval; ///<summary>///If the key value pair exists in the dictionary, returns true///</summary>///<param name= "Item" > key value pair lookup </ Param> public bool Contains (Keyvaluepair<tkey, tvalue> item) {return _lockdictionary.performusingr Eadlock (() => (_mdictionary.containskey () (item. Key) && (_mdictionary.containsvalue (item).
    Value))); public bool ContainsKey (TKey key) {return _lockdictionary.performusingreadlock (() => _mdictionary.cont
    Ainskey (key)); ///<summary>///If the dictionary contains this value, it returnsTrue///</summary>///<param name= "value" > Found values </param> public bool Containsvalue (TValue VA
    Lue) {return _lockdictionary.performusingreadlock (() => _mdictionary.containsvalue (value)); Public icollection<tkey> Keys {get {_lockdictionary.performusingreadlock () => _mdiction ary. 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 (
        => {//If the key does not exist, skip TValue tempval; if (!_mdictionary.trygetvalue (item).
        Key, out TempVal)) return false; If the value does not match, skip return Tempval.equals (item). Value) && _mdictionary.remove (item.
      Key);
    });
///<summary>///Deletes the item that matches the pattern from the dictionary///</summary>    <param name= "Predkey" > key-based optional expression </param>///<param name= "Predvalue" > Value-based option expression </param> public bool Remove (predicate<tkey> Predkey, predicate<tvalue> predvalue) {return _lockdictionar Y.performusingwritelock (() => {//If no key exits if (_mdictionary.keys.count = 0) return tru
        E
        Save the list of items to delete var deletelist = new list<tkey> ();
          Process key foreach (var key in _mdictionary.keys) {var ismatch = false;
          if (Predkey!= null) IsMatch = (Predkey (key));
            If the destination value matches, add it if ((!ismatch) && (predvalue!= null) && (Predvalue (_mdictionary[key)))
          IsMatch = true;
        If we have a match, add to the list if (IsMatch) Deletelist.add (key);
        ///delete all items from the list 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 ();  Icollection<tvalue> Values {get {_lockdictionary.performusingreadlock () => _mdictionary.values); } public TValue This[tkey key] {get {return _lockdictionary.performusingreadlock () => _mdictiona Ry[key]);
    set {_lockdictionary.performusingwritelock (() => _mdictionary[key] = value); ///<summary>///clears dictionary///</summary> public void Clear () {_lockdictionary.perfor
    Musingwritelock (() => _mdictionary.clear ()); } public void CopyTo (Keyvaluepair<tkey, tvalue>[] array, int arrayindex) {_lockdictionary.performusin Greadlock (() => _mdictionary.toarray ().
    CopyTo (array, arrayindex)); }
    /// <summary>///Returns the number of items in the dictionary///</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&gt ;
      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 ();
 }
  }

In the above method of creating a secure dictionary, the main methods and properties of the dictionary are overridden to set the lock on some methods.

The above is the entire content of this article, I hope to help you, but also hope that a lot of support cloud Habitat community!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.