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

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

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

publicvoidAdd(TKeykey,TValuevalue){Insert(key,value,true);}

privatevoidInsert(TKeykey,TValuevalue,booladd){if(key==null){ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);}if(buckets==null)Initialize(0);inthashCode=comparer.GetHashCode(key)&0x7FFFFFFF;inttargetBucket=hashCode%buckets.Length;#ifFEATURE_RANDOMIZED_STRING_HASHINGintcollisionCount=0;#endiffor(inti=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;}#ifFEATURE_RANDOMIZED_STRING_HASHINGcollisionCount++;#endif}intindex;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++;#ifFEATURE_RANDOMIZED_STRING_HASHINGif(collisionCount>HashHelpers.HashCollisionThreshold&&HashHelpers.IsWellKnownEqualityComparer(comparer)){comparer=(IEqualityComparer<TKey>)HashHelpers.GetRandomizedEqualityComparer(comparer);Resize(entries.Length,true);}#endif}

2.Clear():从 Dictionary<TKey, TValue> 中移除所有的键和值。

publicvoidClear(){if(count>0){for(inti=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> 中移除所指定的键的值。

publicboolRemove(TKeykey){if(key==null){ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);}if(buckets!=null){inthashCode=comparer.GetHashCode(key)&0x7FFFFFFF;intbucket=hashCode%buckets.Length;intlast=-1;for(inti=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++;returntrue;}}}returnfalse;}

4.GetEnumerator():返回循环访问 Dictionary<TKey, TValue> 的枚举器。

publicEnumeratorGetEnumerator(){returnnewEnumerator(this,Enumerator.KeyValuePair);}

[Serializable]publicstructEnumerator:IEnumerator<KeyValuePair<TKey,TValue>>,IDictionaryEnumerator{privateDictionary<TKey,TValue>dictionary;privateintversion;privateintindex;privateKeyValuePair<TKey,TValue>current;privateintgetEnumeratorRetType;//WhatshouldEnumerator.Currentreturn?internalconstintDictEntry=1;internalconstintKeyValuePair=2;internalEnumerator(Dictionary<TKey,TValue>dictionary,intgetEnumeratorRetType){this.dictionary=dictionary;version=dictionary.version;index=0;this.getEnumeratorRetType=getEnumeratorRetType;current=newKeyValuePair<TKey,TValue>();}publicboolMoveNext(){if(version!=dictionary.version){ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);}//Useunsignedcomparisonsincewesetindextodictionary.count+1whentheenumerationends.//dictionary.count+1couldbenegativeifdictionary.countisInt32.MaxValuewhile((uint)index<(uint)dictionary.count){if(dictionary.entries[index].hashCode>=0){current=newKeyValuePair<TKey,TValue>(dictionary.entries[index].key,dictionary.entries[index].value);index++;returntrue;}index++;}index=dictionary.count+1;current=newKeyValuePair<TKey,TValue>();returnfalse;}publicKeyValuePair<TKey,TValue>Current{get{returncurrent;}}publicvoidDispose(){}objectIEnumerator.Current{get{if(index==0||(index==dictionary.count+1)){ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);}if(getEnumeratorRetType==DictEntry){returnnewSystem.Collections.DictionaryEntry(current.Key,current.Value);}else{returnnewKeyValuePair<TKey,TValue>(current.Key,current.Value);}}}voidIEnumerator.Reset(){if(version!=dictionary.version){ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);}index=0;current=newKeyValuePair<TKey,TValue>();}DictionaryEntryIDictionaryEnumerator.Entry{get{if(index==0||(index==dictionary.count+1)){ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);}returnnewDictionaryEntry(current.Key,current.Value);}}objectIDictionaryEnumerator.Key{get{if(index==0||(index==dictionary.count+1)){ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);}returncurrent.Key;}}objectIDictionaryEnumerator.Value{get{if(index==0||(index==dictionary.count+1)){ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);}returncurrent.Value;}}}

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

///<summary>///线程安全通用字典///</summary>///<typeparamname="TKey"></typeparam>///<typeparamname="TValue"></typeparam>publicclassTDictionary<TKey,TValue>:IDictionary<TKey,TValue>{///<summary>///锁定字典///</summary>privatereadonlyReaderWriterLockSlim_lockDictionary=newReaderWriterLockSlim();///<summary>///基本字典///</summary>privatereadonlyDictionary<TKey,TValue>_mDictionary;//Variables///<summary>///初始化字典对象///</summary>publicTDictionary(){_mDictionary=newDictionary<TKey,TValue>();}///<summary>///初始化字典对象///</summary>///<paramname="capacity">字典的初始容量</param>publicTDictionary(intcapacity){_mDictionary=newDictionary<TKey,TValue>(capacity);}///<summary>///初始化字典对象///</summary>///<paramname="comparer">比较器在比较键时使用</param>publicTDictionary(IEqualityComparer<TKey>comparer){_mDictionary=newDictionary<TKey,TValue>(comparer);}///<summary>///初始化字典对象///</summary>///<paramname="dictionary">其键和值被复制到此对象的字典</param>publicTDictionary(IDictionary<TKey,TValue>dictionary){_mDictionary=newDictionary<TKey,TValue>(dictionary);}///<summary>///初始化字典对象///</summary>///<paramname="capacity">字典的初始容量</param>///<paramname="comparer">比较器在比较键时使用</param>publicTDictionary(intcapacity,IEqualityComparer<TKey>comparer){_mDictionary=newDictionary<TKey,TValue>(capacity,comparer);}///<summary>///初始化字典对象///</summary>///<paramname="dictionary">其键和值被复制到此对象的字典</param>///<paramname="comparer">比较器在比较键时使用</param>publicTDictionary(IDictionary<TKey,TValue>dictionary,IEqualityComparer<TKey>comparer){_mDictionary=newDictionary<TKey,TValue>(dictionary,comparer);}///<summary>///返回的值<paramrefname="key"/>.如果<paramrefname="key"/>不存在<paramrefname="func"/>被执行并添加到字典///</summary>///<paramname="key">检查的关键</param>///<paramname="func">如果键不存在,委托调用</param>publicTValueGetValueAddIfNotExist(TKeykey,Func<TValue>func){//输入写锁,使绝对确定密钥从我们检查它是否存在的时候添加/删除//到我们添加它的时间,如果它不存在return_lockDictionary.PerformUsingUpgradeableReadLock(()=>{TValuerVal;//如果我们有值,得到它并退出if(_mDictionary.TryGetValue(key,outrVal))returnrVal;//没有找到,所以做函数得到的值_lockDictionary.PerformUsingWriteLock(()=>{rVal=func.Invoke();//添加到字典_mDictionary.Add(key,rVal);returnrVal;});returnrVal;});}///<summary>///将项目添加到字典///</summary>///<paramname="key">添加的关键</param>///<paramname="value">要添加的值</param>publicvoidAdd(TKeykey,TValuevalue){_lockDictionary.PerformUsingWriteLock(()=>_mDictionary.Add(key,value));}///<summary>///将项目添加到字典///</summary>///<paramname="item">要添加的键/值</param>publicvoidAdd(KeyValuePair<TKey,TValue>item){varkey=item.Key;varvalue=item.Value;_lockDictionary.PerformUsingWriteLock(()=>_mDictionary.Add(key,value));}///<summary>///如果值不存在,则添加该值。返回如果值已添加,则为true///</summary>///<paramname="key">检查的关键,添加</param>///<paramname="value">如果键不存在,则添加的值</param>publicboolAddIfNotExists(TKeykey,TValuevalue){boolrVal=false;_lockDictionary.PerformUsingWriteLock(()=>{//如果不存在,则添加它if(!_mDictionary.ContainsKey(key)){//添加该值并设置标志_mDictionary.Add(key,value);rVal=true;}});returnrVal;}///<summary>///如果键不存在,则添加值列表。///</summary>///<paramname="keys">要检查的键,添加</param>///<paramname="defaultValue">如果键不存在,则添加的值</param>publicvoidAddIfNotExists(IEnumerable<TKey>keys,TValuedefaultValue){_lockDictionary.PerformUsingWriteLock(()=>{foreach(TKeykeyinkeys){//如果不存在,则添加它if(!_mDictionary.ContainsKey(key))_mDictionary.Add(key,defaultValue);}});}//添加如果不存在///<summary>///如果值不存在,则添加该值。返回值如果值已添加,则返回true。如果键已经存在,则其值将更新并返回false。///</summary>///<paramname="key">检查的关键,添加</param>///<paramname="value">如果键不存在,则添加的值</param>publicboolAddIfNotExistsElseUpdate(TKeykey,TValuevalue){varrVal=false;_lockDictionary.PerformUsingWriteLock(()=>{//如果不存在,则添加它if(!_mDictionary.ContainsKey(key)){//添加该值并设置标志_mDictionary.Add(key,value);rVal=true;}else_mDictionary[key]=value;});returnrVal;}///<summary>///如果键存在,则更新键的值。如果更新,则返回true///</summary>///<paramname="key"></param>///<paramname="newValue"></param>publicboolUpdateValueIfKeyExists(TKeykey,TValuenewValue){boolrVal=false;_lockDictionary.PerformUsingWriteLock(()=>{//如果我们有密钥,然后更新它if(!_mDictionary.ContainsKey(key))return;_mDictionary[key]=newValue;rVal=true;});returnrVal;}///<summary>///如果键值对存在于字典中,则返回true///</summary>///<paramname="item">键值对查找</param>publicboolContains(KeyValuePair<TKey,TValue>item){return_lockDictionary.PerformUsingReadLock(()=>((_mDictionary.ContainsKey(item.Key))&&(_mDictionary.ContainsValue(item.Value))));}///<summary>///如果键存在于字典中,则返回true///</summary>///<paramname="key">在字典中找到的关键</param>publicboolContainsKey(TKeykey){return_lockDictionary.PerformUsingReadLock(()=>_mDictionary.ContainsKey(key));}///<summary>///如果字典包含此值,则返回true///</summary>///<paramname="value">找到的值</param>publicboolContainsValue(TValuevalue){return_lockDictionary.PerformUsingReadLock(()=>_mDictionary.ContainsValue(value));}///<summary>///将键作为集合返回///</summary>publicICollection<TKey>Keys{get{return_lockDictionary.PerformUsingReadLock(()=>_mDictionary.Keys);}}///<summary>///删除具有此键名称的元素///</summary>///<paramname="key">删除的关键</param>publicboolRemove(TKeykey){return_lockDictionary.PerformUsingWriteLock(()=>(!_mDictionary.ContainsKey(key))||_mDictionary.Remove(key));}///<summary>///删除具有此键名称和值的元素。返回如果项目已删除,则为true。///</summary>///<paramname="item">删除的键</param>publicboolRemove(KeyValuePair<TKey,TValue>item){return_lockDictionary.PerformUsingWriteLock(()=>{//如果键不存在则跳过TValuetempVal;if(!_mDictionary.TryGetValue(item.Key,outtempVal))returnfalse;//如果值不匹配,请跳过returntempVal.Equals(item.Value)&&_mDictionary.Remove(item.Key);});}///<summary>///从字典中删除与模式匹配的项。返回true成功///</summary>///<paramname="predKey">基于键的可选表达式</param>///<paramname="predValue">基于值的选项表达式</param>publicboolRemove(Predicate<TKey>predKey,Predicate<TValue>predValue){return_lockDictionary.PerformUsingWriteLock(()=>{//如果没有键退出if(_mDictionary.Keys.Count==0)returntrue;//保存要删除的项目列表vardeleteList=newList<TKey>();//过程密钥foreach(varkeyin_mDictionary.Keys){varisMatch=false;//如果项匹配谓词,则将该项添加到列表中if(predKey!=null)isMatch=(predKey(key));//如果此项目的值匹配,请添加它if((!isMatch)&&(predValue!=null)&&(predValue(_mDictionary[key])))isMatch=true;//如果我们有匹配,添加到列表if(isMatch)deleteList.Add(key);}//从列表中删除所有项目foreach(varitemindeleteList)_mDictionary.Remove(item);returntrue;});}///<summary>///尝试返回在元素中找到的值<paramrefname="key"/>如果未找到任何值,则返回false///</summary>///<paramname="key">找到的关键</param>///<paramname="value">如果找到该键,则返回值</param>publicboolTryGetValue(TKeykey,outTValuevalue){_lockDictionary.EnterReadLock();try{return_mDictionary.TryGetValue(key,outvalue);}finally{_lockDictionary.ExitReadLock();}}//尝试获取值///<summary>///返回字典中值的集合///</summary>publicICollection<TValue>Values{get{return_lockDictionary.PerformUsingReadLock(()=>_mDictionary.Values);}}///<summary>///值///</summary>///<paramname="key"></param>///<returns></returns>publicTValuethis[TKeykey]{get{return_lockDictionary.PerformUsingReadLock(()=>_mDictionary[key]);}set{_lockDictionary.PerformUsingWriteLock(()=>_mDictionary[key]=value);}}///<summary>///清除字典///</summary>publicvoidClear(){_lockDictionary.PerformUsingWriteLock(()=>_mDictionary.Clear());}///<summary>///将字典的项目复制到键值对数组///</summary>///<paramname="array">将键值对集合复制到</param>///<paramname="arrayIndex">开始复制的索引</param>publicvoidCopyTo(KeyValuePair<TKey,TValue>[]array,intarrayIndex){_lockDictionary.PerformUsingReadLock(()=>_mDictionary.ToArray().CopyTo(array,arrayIndex));}///<summary>///返回字典中的项目数///</summary>publicintCount{get{return_lockDictionary.PerformUsingReadLock(()=>_mDictionary.Count);}}///<summary>///始终返回false///</summary>publicboolIsReadOnly{get{returnfalse;}}///<summary>///枚举器///</summary>///<returns></returns>publicIEnumerator<KeyValuePair<TKey,TValue>>GetEnumerator(){Dictionary<TKey,TValue>localDict=null;_lockDictionary.PerformUsingReadLock(()=>localDict=newDictionary<TKey,TValue>(_mDictionary));//获取枚举器return((IEnumerable<KeyValuePair<TKey,TValue>>)localDict).GetEnumerator();}///<summary>///获取枚举器///</summary>System.Collections.IEnumeratorSystem.Collections.IEnumerable.GetEnumerator(){Dictionary<TKey,TValue>localDict=null;_lockDictionary.PerformUsingReadLock(()=>localDict=newDictionary<TKey,TValue>(_mDictionary));returnlocalDict.GetEnumerator();}}

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