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///≪/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 </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; }///<SUMMARY>
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> ;
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!