7

如果你有对象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 的,还是自定义实现?更重要的是,为什么?

4

2 回答 2

5

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

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

当然,ICollection<TValue>如果需要的话,你可以隐式转换对象,所以这里没有功能损失,只是一点(微)优化。

在您的情况下,您没有理由不能 return 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>. 请记住:始终进行基准测试,永远不要过早地优化。

于 2013-04-23T14:23:28.907 回答
1

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

通过返回一个实现IEnumerable而不是键入结果的实际类,因为IEnumerable它们也有能力包含一些额外的功能。例如,两个集合都有一个Count属性,从任何IEnumerable.

于 2013-04-23T14:23:43.263 回答