我正在制作一个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普通字典类如何处理这个实现?
发布于 2015-07-23 20:26:12
如果您想要查看.NET框架中的某些内容是如何实现的,可以简单地查看一下参考源。例如,下面是字典类的代码。如果您要查找的代码不是托管在Reference上,您还可以使用许多.NET反编译器中的一个来查看任何.NET框架库(例如免费ILSpy)的源代码。
为了更具体地回答您的问题,正如Reference所示,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类中,所以它可以访问和使用字典的一些私有成员,如version和entries,您通常无法从外部访问它们。
https://stackoverflow.com/questions/31596167
复制相似问题