为什么反射器不显示 IDictionary<TKey, TValue> 实现 IEnumerable<T>?
Why does the reflector not show that IDictionary<TKey, TValue> implements IEnumerable<T>?
我注意到,如果变量声明为 IDictionary<TKey, TValue>
,则键值对只能添加到字典中。这让我进一步挖掘兔子洞,让我发现似乎有一个奇怪的差异:
Microsoft 文档明确确认 IDictionary<TKey, TValue>
实现了 IEnumerable<T>
Microsoft Docs Screenshot - IDictionary Implements implements IEnumerable<T>
在 mscorlib 上使用 Visual Studio 的 Reflector Tool,IDictionary<TKey, TValue>
似乎没有实现 IEnumerable<T>
Reflector Tool Screenshot - mscorlib, IDictionary seems to not implement IEnumerable<T>
任何解释都将有助于满足这个好奇心!
它确实表明它实现了IEnumerable<T>
:
对于 Dictionary<TKey, TValue>
,集合元素的类型是 KeyValuePair<TKey, TValue>
。本质上,字典是 key/value 对(所选 key/value 类型)的可枚举列表,因此它实现了 IEnumerable<KeyValuePair<TKey, TValue>>
接口。
MSDN 文档显示 通用 IEnumerable<T>
接口和更具体的 IEnumerable<KeyValuePair<TKey, TValue>>
,但它们指的是相同的实现。 IEnumerable<T>
中的 T
实际上是 KeyValuePair<TKey, TValue>
.
这不是真实代码缺少记录功能的情况。这是 MSDN 两次记录相同接口实现的情况,通过引用通用 IEnumerable<T>
和 更具体的类型,它显示了 T
被定义的内容作为(即 KeyValuePair<TKey, TValue>
)。
如果您考虑一下,Dictionary<TKey, TValue> : IEnumerable<T>
是没有意义的,因为 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<TKey, TValue>
由3种不同的类型组成,它们都符合规则:
KeyValuePair
是硬编码的(这是已知类型)
TKey
是 Dictionary<TKey, TValue>
定义的泛型类型
TValue
是 Dictionary<TKey, TValue>
定义的泛型类型
因此这个 class 定义在句法上是有效的。
我注意到,如果变量声明为 IDictionary<TKey, TValue>
,则键值对只能添加到字典中。这让我进一步挖掘兔子洞,让我发现似乎有一个奇怪的差异:
Microsoft 文档明确确认
IDictionary<TKey, TValue>
实现了IEnumerable<T>
Microsoft Docs Screenshot - IDictionary Implements implementsIEnumerable<T>
在 mscorlib 上使用 Visual Studio 的 Reflector Tool,
IDictionary<TKey, TValue>
似乎没有实现IEnumerable<T>
Reflector Tool Screenshot - mscorlib, IDictionary seems to not implement
IEnumerable<T>
任何解释都将有助于满足这个好奇心!
它确实表明它实现了IEnumerable<T>
:
对于 Dictionary<TKey, TValue>
,集合元素的类型是 KeyValuePair<TKey, TValue>
。本质上,字典是 key/value 对(所选 key/value 类型)的可枚举列表,因此它实现了 IEnumerable<KeyValuePair<TKey, TValue>>
接口。
MSDN 文档显示 通用 IEnumerable<T>
接口和更具体的 IEnumerable<KeyValuePair<TKey, TValue>>
,但它们指的是相同的实现。 IEnumerable<T>
中的 T
实际上是 KeyValuePair<TKey, TValue>
.
这不是真实代码缺少记录功能的情况。这是 MSDN 两次记录相同接口实现的情况,通过引用通用 IEnumerable<T>
和 更具体的类型,它显示了 T
被定义的内容作为(即 KeyValuePair<TKey, TValue>
)。
如果您考虑一下,Dictionary<TKey, TValue> : IEnumerable<T>
是没有意义的,因为 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<TKey, TValue>
由3种不同的类型组成,它们都符合规则:
KeyValuePair
是硬编码的(这是已知类型)TKey
是Dictionary<TKey, TValue>
定义的泛型类型
TValue
是Dictionary<TKey, TValue>
定义的泛型类型
因此这个 class 定义在句法上是有效的。