C#创建安全的字典(Dictionary)存储结构
在上面介绍过栈(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_HASHING
intcollisionCount=0;
#endif
for(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_HASHING
collisionCount++;
#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_HASHING
if(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.MaxValue
while((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);
}
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);
}
});
}
publicboolAddIfNotExistsElseUpdate(TKeykey,TValuevalue)
{
varrVal=false;
_lockDictionary.PerformUsingWriteLock(()=>
{
//如果不存在,则添加它
if(!_mDictionary.ContainsKey(key))
{
//添加该值并设置标志
_mDictionary.Add(key,value);
rVal=true;
}
else
_mDictionary[key]=value;
});
returnrVal;
}
///<summary>
///如果键存在,则更新键的值。
///</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))));
}
publicboolContainsKey(TKeykey)
{
return_lockDictionary.PerformUsingReadLock(()=>_mDictionary.ContainsKey(key));
}
///<summary>
///如果字典包含此值,则返回true
///</summary>
///<paramname="value">找到的值</param>
publicboolContainsValue(TValuevalue)
{
return_lockDictionary.PerformUsingReadLock(()=>_mDictionary.ContainsValue(value));
}
publicICollection<TKey>Keys
{
get{return_lockDictionary.PerformUsingReadLock(()=>_mDictionary.Keys);}
}
publicboolRemove(TKeykey)
{
return_lockDictionary.PerformUsingWriteLock(()=>(!_mDictionary.ContainsKey(key))||_mDictionary.Remove(key));
}
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>
///从字典中删除与模式匹配的项
///</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;
});
}
publicboolTryGetValue(TKeykey,outTValuevalue)
{
_lockDictionary.EnterReadLock();
try
{
return_mDictionary.TryGetValue(key,outvalue);
}
finally
{
_lockDictionary.ExitReadLock();
}
}
publicICollection<TValue>Values
{
get{return_lockDictionary.PerformUsingReadLock(()=>_mDictionary.Values);}
}
publicTValuethis[TKeykey]
{
get{return_lockDictionary.PerformUsingReadLock(()=>_mDictionary[key]);}
set{_lockDictionary.PerformUsingWriteLock(()=>_mDictionary[key]=value);}
}
///<summary>
///清除字典
///</summary>
publicvoidClear()
{
_lockDictionary.PerformUsingWriteLock(()=>_mDictionary.Clear());
}
publicvoidCopyTo(KeyValuePair<TKey,TValue>[]array,intarrayIndex)
{
_lockDictionary.PerformUsingReadLock(()=>_mDictionary.ToArray().CopyTo(array,arrayIndex));
}
///<summary>
///返回字典中的项目数
///</summary>
publicintCount
{
get{return_lockDictionary.PerformUsingReadLock(()=>_mDictionary.Count);}
}
publicboolIsReadOnly
{
get{returnfalse;}
}
publicIEnumerator<KeyValuePair<TKey,TValue>>GetEnumerator()
{
Dictionary<TKey,TValue>localDict=null;
_lockDictionary.PerformUsingReadLock(()=>localDict=newDictionary<TKey,TValue>(_mDictionary));
return((IEnumerable<KeyValuePair<TKey,TValue>>)localDict).GetEnumerator();
}
System.Collections.IEnumeratorSystem.Collections.IEnumerable.GetEnumerator()
{
Dictionary<TKey,TValue>localDict=null;
_lockDictionary.PerformUsingReadLock(()=>localDict=newDictionary<TKey,TValue>(_mDictionary));
returnlocalDict.GetEnumerator();
}
}
以上创建安全的字典方法中,主要对字典的一些方法和属性进行重写操作,对某些方法进行锁设置。
以上就是本文的全部内容,希望对大家有所帮助,同时也希望多多支持毛票票!