none
C# dictionary<TKey,TValue>加入键和值后数据类型怎么就变成了KeyValuePair<TKey, TValue>,代码是怎么实现的? RRS feed

  • 问题

  • 例如 如下图,我键保存了个字符串"one" 值保存了个时间类型,存到字典里的类型怎么就成了KeyValuePair<string,object>了,字典里保存键跟值主要调用的是private void Insert(TKey key, TValue value, bool add)方法,但是在这个方法里没看到把键和值转成KeyValuePair,请问微软是怎么把键和值转成KeyValuePair的?

    2015年8月3日 9:32

答案

  • 因为Enumerate 的时候是使用GetEnumerator函数,而且实现了 IEnumerable<KeyValuePair<TKey, TValue>> 接口

    public Dictionary<TKey, TValue>.Enumerator GetEnumerator()
    {
        return new Dictionary<TKey, TValue>.Enumerator(this2);
    }

    而Enumerator的定义是:

    public struct Enumerator : IEnumerator<KeyValuePair<TKey, TValue>>, IDisposable, IDictionaryEnumerator, IEnumerator

     {
                internal const int DictEntry = 1;
                internal const int KeyValuePair = 2;
                private Dictionary<TKey, TValue> dictionary;
                private int version;
                private int index;
                private KeyValuePair<TKey, TValue> current;
                private int getEnumeratorRetType;
                /// <summary>Gets the element at the current position of the enumerator.</summary>
                /// <returns>The element in the <see cref="T:System.Collections.Generic.Dictionary`2" /> at the current position of the enumerator.</returns>
                [__DynamicallyInvokable]
                public KeyValuePair<TKey, TValue> Current
                {
                    [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
                    get
                    {
                        return this.current;
                    }
                }

    .....

    当调试器去取值的时候,是使用的Enumerate, 取到的数据类型就是KeyValuePair<TKey, TValue>了。

    • 已建议为答案 Barry Wang 2015年8月4日 5:05
    • 已标记为答案 齐永刚 2015年8月4日 6:13
    2015年8月4日 2:41

全部回复

  • 首先:不能直接用对象当成布尔类型用作if判断,应该是使用:

    if(discusOne!=null)
    {
      ……
    }

    其次:你的 Dictionary的Value类型应该是DateTime类型,不是object类型:

    Dictionary<string,DateTime> dic1 = new Dictionary<string,DateTime>();


    ASP.NET Forum
    Other Discussion Forums
    FreeRice Donate
    Issues to report
    Free Tech Books Search and Download

    2015年8月3日 9:42
    版主
  • 首先:不能直接用对象当成布尔类型用作if判断,应该是使用:

    if(discusOne!=null)
    {
      ……
    }

    其次:你的 Dictionary的Value类型应该是DateTime类型,不是object类型:

    Dictionary<string,DateTime> dic1 = new Dictionary<string,DateTime>();


    ASP.NET Forum
    Other Discussion Forums
    FreeRice Donate
    Issues to report
    Free Tech Books Search and Download

    2015年8月3日 9:43
    版主
  • 这是继承 IDictionary 接口的原因。

    IEnumerator< T > 中返回了 KeyValuePair 。

                           current = new KeyValuePair<TKey, TValue>(dictionary.entries[index].key, dictionary.entries[index].value);

    2015年8月3日 9:47
  •  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);


    关键是dictionary<TKey,TValue>在哪里调用的这方法看不到


    2015年8月4日 2:39
  • 因为Enumerate 的时候是使用GetEnumerator函数,而且实现了 IEnumerable<KeyValuePair<TKey, TValue>> 接口

    public Dictionary<TKey, TValue>.Enumerator GetEnumerator()
    {
        return new Dictionary<TKey, TValue>.Enumerator(this2);
    }

    而Enumerator的定义是:

    public struct Enumerator : IEnumerator<KeyValuePair<TKey, TValue>>, IDisposable, IDictionaryEnumerator, IEnumerator

     {
                internal const int DictEntry = 1;
                internal const int KeyValuePair = 2;
                private Dictionary<TKey, TValue> dictionary;
                private int version;
                private int index;
                private KeyValuePair<TKey, TValue> current;
                private int getEnumeratorRetType;
                /// <summary>Gets the element at the current position of the enumerator.</summary>
                /// <returns>The element in the <see cref="T:System.Collections.Generic.Dictionary`2" /> at the current position of the enumerator.</returns>
                [__DynamicallyInvokable]
                public KeyValuePair<TKey, TValue> Current
                {
                    [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
                    get
                    {
                        return this.current;
                    }
                }

    .....

    当调试器去取值的时候,是使用的Enumerate, 取到的数据类型就是KeyValuePair<TKey, TValue>了。

    • 已建议为答案 Barry Wang 2015年8月4日 5:05
    • 已标记为答案 齐永刚 2015年8月4日 6:13
    2015年8月4日 2:41
  • 非常感谢   Simon YunZhi Cai,我认为你说的是正确的。
    2015年8月4日 6:12