C#中保留订单的数据结构

时间:2010-04-27 15:55:03

标签: c# data-structures

MSDN没有关于数据结构的顺序保留属性的信息。所以我一直在假设:

  • HashTable和HashSet 保留插入顺序(即“散列”中有赠品)
  • 字典和列表执行保留广告订单。

由此我推断,如果我有一个定义曲线的Dictionary<double, double> foofoo.Keys.ToList()foo.Values.ToList()会给我一个有序的列表,其中包含该曲线的范围和域,而不会弄乱用它?

4 个答案:

答案 0 :(得分:37)

您不应期望常规Dictionary<TKey,TValue>中的键或值可以按任何顺序维护。在SortedDictionary<TKey,TValue>中,键和值按键的值按顺序维护 - 这与插入顺序不同。

.NET框架中唯一保留插入顺序的内置字典是System.Collections.Specialized.OrderedDictionary。不幸的是,这个类不是通用的 - 但是,编写一个通用的包装器并不是非常困难。请记住,在处理值类型(如intdouble)时,它将导致键/值的装箱(通用词典不会对值类型施加限制)。

答案 1 :(得分:0)

我已经对Dictionary 排序进行了广泛的测试。 我发现了这一点: 只要我将新的键/值对添加到集合中,顺序就保持不变。 如果我替换了一个已经存在的元素,或者如果我删除了一些元素,更糟的是,以下插入 不能保证在字典的尾部

在特定情况下,假设字典键的顺序与插入的顺序完全相同,我有一个非常讨厌的错误,并且我发现该错误是键的意外重新分配,因此该顺序无法保留。 / p>

要保留顺序,您必须包装对字典的所有写访问权限(添加除外),并编写一个伪算法,如下所示:

1-将字典复制到常规列表(键/值对) 2-删除/替换/修改列表 3-清除字典,然后将所有键/值对重新添加回字典

您愿意使用Dictionary构造函数预分配足够的元素来存储您的实际列表,等于list.count + 1

这种丑陋的方式解决了该错误,但是我可以向您保证Dictionary 不会保留键的插入顺序,除非只是在尾部插入。

答案 2 :(得分:-1)

正如@Anton所指出的,Dictionary<TKey,TValue>是一个无序的集合。正确返回你的价值观是巧合,最终会失败。如果您需要有一个有序的哈希表,则应使用SortedDictionary<TKey,TValue>

答案 3 :(得分:-7)

一定要依靠Dictionary<TKey, TValue>来保持订购!

虽然Dictionary<TKey, TValue>明确指出枚举排序未定义,但我们测试它确实保留了插入排序(至少只要您不从中删除项目)。如果有人可以提供反对它的测试,我们会非常感兴趣,因为我们的生产代码依赖于它。

您可以采取相同的方法,为自己节省一些精力,为客户节省一些钱。

当然,Microsoft可能会在未来的.NET版本中更改Dictionary实现,但如果发生这种情况,您的自动化测试会检测到它,并且您可以在那时用另一个容器替换Dictionary,对吗?