2

起初我的想法是“这是一种基于哈希的数据类型,然后它是未排序的”。

然后因为我要使用它,所以我深入研究了这个问题,发现这个类实现了IEnumerable,而且这篇文章证实了可以迭代这种数据。

所以,我的问题是:如果我使用foreachaConcurrentDictionary来读取元素的顺序是什么?

然后,作为第二个问题,我想知道其接口继承的排序方法是否有任何用途。如果我在新订单上调用排序方法ConcurrentDictionary将持续存在(例如对于传入foreach)?。

希望我已经说清楚了

4

3 回答 3

6

当前的实现对元素的顺序没有任何承诺。未来的实现可以轻松更改枚举元素的顺序。

因此,您的代码不应依赖于该顺序。

来自Dictionary<TKey, TValue> msdn 文档

返回项目的顺序未定义。

(我找不到任何关于 的参考资料ConcurrentDictionary,但同样的原则也适用。)

当您提到“其接口继承的排序方法”时,您的意思是 LINQ 扩展吗?喜欢OrderBy?如果是这样,这些扩展纯粹是功能性的,并且总是返回一个新的集合。所以,回答你的问题“新秩序会持续吗?”:不,不会。但是,您可以像这样使用它:

foreach(KeyValuePair<T1, T2> kv in dictionary.OrderBy(...))
{

}
于 2013-11-29T15:52:42.110 回答
1

如果我在 ConcurrentDictionary 上使用 foreach ,这是我读取元素的顺序?

您按照它们所属的存储桶的顺序获取它们,如果一个存储桶包含多个项目,则这些项目按照它们被添加的顺序。但正如其他人所说,这是一个你不应该依赖的实现细节。

我想知道它的接口继承的排序方法是否有任何用途。如果我在 ConcurrentDictionary 上调用排序方法,新订单将持续存在(例如对于传入的 foreach)?

我假设您指的是接口OrderBy()上的扩展方法。IEnumnerable<KeyValuePair<TKey, TValue>>没有什么会坚持下去。此方法返回另一个IEnumnerable<KeyValuePair<TKey, TValue>>. 字典保持原样。

于 2013-11-29T16:13:27.853 回答
0

如果你不是特别小心,听起来你可能会自找麻烦。正如 dcastro 所提到的,元素的顺序不能保证。一个比较麻烦的问题是一个 ConcurrentDictionary 可以随时被其他线程改变。这意味着即使确保了订单,也没有理由不会错过在您迭代时添加的新项目。除非您知道可以阻止其他线程更改字典,否则迭代它可能不是一个好主意。

于 2013-11-29T15:58:32.293 回答