首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >实现GetEnumerator的IDictionary

实现GetEnumerator的IDictionary
EN

Stack Overflow用户
提问于 2015-07-23 19:12:31
回答 1查看 1.3K关注 0票数 2

我正在制作一个LinkedHashMap作为VB.NET应用程序的池,我通过组合而不是继承来扩展,因为很多字典方法都不是声明为虚拟的。

我该怎么处理呢?

代码语言:javascript
运行
复制
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

普通字典类如何处理这个实现?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-07-23 20:26:12

如果您想要查看.NET框架中的某些内容是如何实现的,可以简单地查看一下参考源。例如,下面是字典类的代码。如果您要查找的代码不是托管在Reference上,您还可以使用许多.NET反编译器中的一个来查看任何.NET框架库(例如免费ILSpy)的源代码。

为了更具体地回答您的问题,正如Reference所示,GetEnumerator方法在Dictionary类中的实现如下:

代码语言:javascript
运行
复制
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类的代码:

代码语言:javascript
运行
复制
[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类中,所以它可以访问和使用字典的一些私有成员,如versionentries,您通常无法从外部访问它们。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31596167

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档