起初我的想法就像“这是一种基于散列的数据类型,然后它是未分类的”。
然后,由于我即将使用它,我深入研究了这个问题,发现这个类实现IEnumerable
并且this post确认可以迭代这种数据。< / p>
所以,我的问题是:如果我使用foreach
而不是ConcurrentDictionary
这是我读取元素的顺序吗?
然后,作为第二个问题,我想知道它的接口继承的排序方法是否具有任何用途。如果我在ConcurrentDictionary
上调用排序方法,新订单将会保留(例如传入的foreach
)?
希望我已经说清楚了
答案 0 :(得分:6)
当前的实现没有对元素的顺序做出任何承诺。 未来的实现可以轻松更改枚举元素的顺序。
因此,您的代码不应该依赖于该顺序。
来自Dictionary<TKey, TValue>
msdn docs:
未定义项目的返回顺序。
(我找不到关于ConcurrentDictionary
的任何参考,但同样的原则适用。)
当您引用“其接口继承的排序方法”时,您的意思是LINQ扩展吗?像OrderBy
一样?如果是这样,这些扩展名纯粹是功能性的,并且总是返回一个新的集合。那么,回答你的问题“新订单会持续存在吗?”:不,它不会。但是你可以像这样使用它:
foreach(KeyValuePair<T1, T2> kv in dictionary.OrderBy(...))
{
}
答案 1 :(得分:1)
如果我使用foreach而不是ConcurrentDictionary,这是我读取元素的顺序?
您按照它们所属的存储桶顺序获取它们,如果存储桶包含多个项目,则这些项目按其添加顺序排列。 但正如其他人所说,这是一个你不应该依赖的实现细节。
我想知道它的接口是否继承了排序方法 有任何用途。如果我调用一个排序方法 ConcurrentDictionary新订单将持续存在(例如对于 传入的foreach)?。
我假设您在OrderBy()
界面上引用了IEnumnerable<KeyValuePair<TKey, TValue>>
扩展方法。没有什么能坚持下去。此方法返回另一个IEnumnerable<KeyValuePair<TKey, TValue>>
。字典保持不变。
答案 2 :(得分:0)
如果你不是特别小心的话,听起来你可能会遇到麻烦。正如dcastro所提到的,元素的顺序无法确保。一个更麻烦的问题是ConcurrentDictionary可以随时被其他线程更改。这意味着即使确保了订单,也没有理由为什么在迭代时添加新项目不会错过。除非你知道你可以阻止其他线程更改字典,否则迭代它可能不是一个好主意。