我正在使用LinkedHashMap
作为VB.NET应用程序的池,并且我通过组合而不是继承进行扩展,因为很多字典方法都没有声明虚拟
我该如何处理:
Public NotInheritable Class LinkedDictionary(Of TKey, TValue)
Implements IDictionary(Of TKey, TValue),
Private ReadOnly maxCapacity As Integer
Private ReadOnly dictionary As New Dictionary(Of TKey, TValue)()
Private ReadOnly queue As New Queue(Of TKey, TValue)()
' ...
Public Sub Add(ByVal key As TKey, ByVal value As TValue) _
Implements ICollection(Of KeyValuePair(Of TKey, TValue)).Add
dictionary.Add(key, value)
queue.Enqueue(key)
If queue.Count() > maxCapacity Then
dictionary.Remove(queue.Dequeue())
End If
End Sub
' ...
Public Function GetEnumerator() As IEnumerator(Of KeyValuePair(Of TKey, TValue)) _
Implements IEnumerable(Of KeyValuePair(Of TKey, TValue)).GetEnumerator
Return dictionary.GetEnumerator()
End Function
Public Function GetEnumerator2() As System.Collections.IEnumerator _
Implements System.Collections.IEnumerable.GetEnumerator
Return dictionary.GetEnumerator()
' ??? there's only one GetEnumerator Method in Dictionary(Of TKey, TValue)
End Function
End Class
常规字典类如何处理此实现?
答案 0 :(得分:3)
如果您想查看.NET框架中的某些内容是如何实现的,您只需查看Reference Source即可。例如,这是code for the Dictionary class。如果您要查找的代码未托管在Reference Source上,您还可以使用众多.NET反编译器之一来查看任何.NET Framework库的源代码(例如免费的{{3} })。
更具体地回答您的问题,正如参考资料显示的那样,GetEnumerator
类中Dictionary
方法的实现如下:
public Enumerator GetEnumerator() {
return new Enumerator(this, Enumerator.KeyValuePair);
}
IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator() {
return new Enumerator(this, Enumerator.KeyValuePair);
}
前者是IDictionary.GetEnumerator
的实现,后者是IDictionary(Of TKey, TValue).GetEnumerator
的实现。所以它所做的就是创建一个新的Enumerator
类(它是在Dictionary
类中声明的嵌套类),将自己作为源字典参数。
它有点长,但这是嵌套Enumerator
类的代码:
[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;
}
}
}
正如您所看到的,由于Enumerator
类嵌套在Dictionary
类中,因此它可以访问并使用某些字典的私有成员,例如{{1}和version
您通常无法从外部访问。