我的Custom Dictionary.Values应该返回什么类型?

时间:2013-04-23 14:19:01

标签: c# collections dictionary language-concepts

如果您有对象Dictionary<k, v> myDictionary,则myDictionary.Values的类型为Dictionary<k, v>.ValueCollection,而myDictionary.Keys的类型为Dictionary<k, v>.KeyCollection

我不明白为什么myDictionary.Values的类型不像IEnumerable<v>IList<v>或其他类似的内容。

现在,考虑到这一点,如果我创建一个自定义类型的字典; Dictionary2<k1, k2, v>myCustomDictionary.Values应该返回IEnumerable<v>还是ValueCollection的自定义工具?更重要的是,为什么?

2 个答案:

答案 0 :(得分:5)

请注意,Dictionary<TKey, TValue>.ValueCollection确实实现了ICollection<TValue>,因此也IEnumerable<TValue>

属性类型的原因可能是出于性能原因:由于此类的方法不是虚拟的,因此可以在JIT编译期间精确解析它们,而不是需要vtable在运行时查找每个方法调用。这有效地从您在集合上调用的每个方法中删除了一个级别的间接。 (它还为JIT提供了内联这些方法调用的选项!)

当然,如果需要,您可以将对象隐式转换为ICollection<TValue>,因此这里不会丢失任何功能,只需进行一些(微)优化。

在您的情况下,没有理由不能返回ICollection<TValue>,但如果您愿意,可以返回更具体的类型。如果这样做,那么您将必须显式实现接口属性IDictionary<TKey, TValue>.Values以满足接口:

private ValueCollection valueCollection;

public ValueCollection Values
{
    get { return valueCollection; }
}

ICollection<TValue> IDictionary<TKey, TValue>.Values
{
    get { return valueCollection; }
}

这正确地暗示,如果使用类型为您的集合类型的引用,则只会向该类的使用者提供任何性能优势;如果他们引用IDictionary<TKey, TValue>,则不会有性能优势,因为他们必须选择,但无论如何都要通过ICollection<TValue>访问您的价值集。

在我的工作中,我没有发现性能差异足以保证返回比ICollection<TValue>更具体的内容。请记住:始终是基准,永远不要过早优化。

答案 1 :(得分:1)

Dictionary<k, v>.ValueCollection实施IEnumerable<v>Dictionary<k, v>.KeyCollection实施IEnumerable<k>。它不像返回的结果是不可枚举的。

通过返回实现IEnumerable的实际类而不是将结果键入为IEnumerable,它们还能够包含一些额外的功能。例如,两个集合都有Count属性,无法从任何IEnumerable轻松访问。