【问题标题】:Why does the reflector not show that IDictionary<TKey, TValue> implements IEnumerable<T>?为什么反射器没有显示 IDictionary<TKey, TValue> 实现了 IEnumerable<T>?
【发布时间】:2021-02-19 04:19:23
【问题描述】:

我注意到只有将变量声明为IDictionary&lt;TKey, TValue&gt; 时,才能将键值对添加到字典中。这导致我进一步挖掘兔子洞,导致我发现似乎有一个奇怪的差异:

  1. Microsoft Docs 明确确认 IDictionary&lt;TKey, TValue&gt; 实现 IEnumerable&lt;T&gt;
    Microsoft Docs Screenshot - IDictionary Implements implements IEnumerable&lt;T&gt;

  2. 在 mscorlib 上使用 Visual Studio 的 Reflector Tool,IDictionary&lt;TKey, TValue&gt; 似乎没有实现 IEnumerable&lt;T&gt;

    Reflector Tool Screenshot - mscorlib, IDictionary seems to not implement IEnumerable&lt;T&gt;

任何解释都会有助于满足这个好奇的心!

【问题讨论】:

  • 你的截图显示,它确实实现了IEnumerable&lt;KeyValuePair&lt;TKey, TValue&gt;&gt;,其中T被扣除为KeyValuePair&lt;TKey, TValue&gt;
  • 在这种情况下T 是什么?我们只有IDictionary&lt;TKey, TValue&gt;
  • @Carsten 我也这么想,但对我来说没有多大意义,因为它已经用IEnumrable&lt;KeyValue&lt;指定了
  • 好吧,文档是错误的。它不可能实现IEnumerable&lt;T&gt;,因为T不是IDictionary的泛型参数!但是请注意,IEnumerable(所有风格)无论如何都与您的问题无关,因为IEnumerable 不包含任何添加方法。 ICollection 可以,但该方法通常会显式实现,以免与字典自己的 Add 方法(获取键和值)混淆。

标签: c# .net visual-studio ienumerable idictionary


【解决方案1】:

确实表明它实现了IEnumerable&lt;T&gt;

对于Dictionary&lt;TKey, TValue&gt;,集合元素的类型是KeyValuePair&lt;TKey, TValue&gt;。本质上,字典是键/值对的可枚举列表(所选键/值类型),因此它实现了IEnumerable&lt;KeyValuePair&lt;TKey, TValue&gt;&gt; 接口。

MSDN 文档显示了通用的IEnumerable&lt;T&gt; 接口和更具体的IEnumerable&lt;KeyValuePair&lt;TKey, TValue&gt;&gt;,但它们指的是相同的实现。 IEnumerable&lt;T&gt; 中的 T 实际上是 KeyValuePair&lt;TKey, TValue&gt;

这不是真实代码缺少文档功能的情况。这是 MSDN 两次记录相同接口实现的案例,通过引用通用 IEnumerable&lt;T&gt; 更具体的类型,它显示了 T 的定义(即 KeyValuePair&lt;TKey, TValue&gt;) .


如果你仔细想想,Dictionary&lt;TKey, TValue&gt; : IEnumerable&lt;T&gt; 是没有意义的,因为T 从来没有被定义过。出现在: 之后的任何泛型类型必须在: 之前进行硬编码或定义为泛型类型,而T 既没有硬编码也没有定义,因此它不是有效的语法。

您可以轻松确认此行为:

public class Foo : IEnumerable<string> { } // allowed, T is hardcoded as string

public class Foo<T> : IEnumerable<T> { }   // allowed, T is defined in Foo<T>

public class Foo : IEnumerable<T> { }      // error, T is neither hardcoded nor defined

知道了这一点,我们再回头看看字典:

public class Dictionary<TKey, TValue> : IEnumerable<T>  // error, T is neither hardcoded nor defined

但是这个有效的:

public class Dictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>

KeyValuePair&lt;TKey, TValue&gt;由3种不同的类型组成,它们都符合规则:

  • KeyValuePair 是硬编码的(它是已知类型)
  • TKey 是从 Dictionary&lt;TKey, TValue&gt; 定义的泛型类型
  • TValue 是从 Dictionary&lt;TKey, TValue&gt; 定义的泛型类型

因此这个类定义在语法上是有效的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-08
    • 2011-01-16
    • 1970-01-01
    • 2014-02-19
    • 1970-01-01
    • 1970-01-01
    • 2012-07-25
    相关资源
    最近更新 更多