【问题标题】:OrderedDictionary and DictionaryOrderedDictionary 和 Dictionary
【发布时间】:2013-05-17 15:32:16
【问题描述】:

我正在寻找一种方法让我的Dictionary 以与添加它们相同的顺序枚举其KeyValuePair。现在,Dictionary's documentation 明确指出:

出于枚举的目的,字典中的每个项目都被视为一个KeyValuePair<TKey, TValue> 结构,表示一个值及其键。返回项目的顺序未定义。

我发现我需要的是OrderedDictionary,但作为怀疑论者,我决定自己尝试一下:

OrderedDictionary od = new OrderedDictionary();
Dictionary<String, String> d = new Dictionary<String, String>();

for (int i = 0; i < 10; i++)
{
    od.Add("key" + i, "value" + i);
    d.Add("key" + i, "value" + i);
}

System.Console.WriteLine("OrderedDictionary");
foreach (DictionaryEntry de in od) {
    System.Console.WriteLine(de.Key + ", " + de.Value);
}

System.Console.WriteLine("Dictionary");
foreach (var tmp in d) {
    System.Console.WriteLine(tmp.Key + ", " + tmp.Value);
}

输出:

OrderedDictionary
key0, value0
key1, value1
key2, value2
...

Dictionary
key0, value0
key1, value1
key2, value2
...

如您所见,两者都是有序的,这就提出了两个问题:

在哪种情况下,Dictionary 给出的顺序与添加值的顺序不同? 我的第一个foreach 循环是否保证我以相同的顺序检索我的KeyValuePair,还是我必须使用索引?

【问题讨论】:

  • Adding 集合时尝试使用随机键并查看差异。
  • 仅供参考:@I4V 试过了,没变。
  • 字典文档的重要部分是“[t]he order [...] is undefined”,这意味着实现不包含保证顺序的逻辑。换句话说,仅仅因为您现在遵守给定的顺序并不意味着您将始终遵守相同的顺序,所以不要依赖它。

标签: c# dictionary ordereddictionary


【解决方案1】:

你做错了。您不仅需要将值按顺序插入字典中,还需要删除一些元素,然后查看顺序如何变化。下面的代码演示了这一点:

OrderedDictionary od = new OrderedDictionary();
Dictionary<String, String> d = new Dictionary<String, String>();
Random r = new Random();

for (int i = 0; i < 10; i++)
{
    od.Add("key" + i, "value" + i);
    d.Add("key" + i, "value" + i);
    if (i % 3 == 0)
    {
        od.Remove("key" + r.Next(d.Count));
        d.Remove("key" + r.Next(d.Count));
    }
}

System.Console.WriteLine("OrderedDictionary");
foreach (DictionaryEntry de in od) {
    System.Console.WriteLine(de.Key + ", " +de.Value);
}

System.Console.WriteLine("Dictionary");
foreach (var tmp in d) {
    System.Console.WriteLine(tmp.Key + ", " + tmp.Value);
}

打印类似于(OrderedDictionary 总是有序的):

OrderedDictionary
key3, value3
key5, value5
key6, value6
key7, value7
key8, value8
key9, value9
Dictionary
key7, value7
key4, value4
key3, value3
key5, value5
key6, value6
key8, value8
key9, value9

【讨论】:

  • 如果我只枚举字典怎么办?据我了解,在这种情况下,它们的工作方式相同。
  • @DeadlyJesus 看,在添加新项目后,字典通过将容量增加 2 来调整内部数据结构的大小。这导致使用新键将元素再次插入数组Dictionary&lt;TKey, TValue&gt;.Entry[] entries;。这可能会导致更改您的项目的顺序。我将尝试通过示例来展示这一点(仍然没有弄清楚如何展示这一点),但如果您依赖订单,即使您只是在其中插入值,我也会使用 OrderedDictionary
  • @DeadlyJesus 另一个重要的一点是 OrderedDictionary 保证键已排序,而 Dictionary 则没有。只要他们的“合同”/定义得到履行,没有什么能阻止 C# 的 Dictionary 内部实现发生变化!所以也许在未来的某个地方你会改用 Mono,或者升级到 C#6.5,或者类似的东西;突然间你会遇到意想不到的错误。
  • @ANeves 我不确定我是否同意 OrderedDictionary 对它的键进行排序,如果这就是你的意思。 OrderedDictionary 绝不是排序字典;它只是在添加项目时维护它们的顺序。
  • @ANeves 现在读起来更好。我很惊讶 OrderedDictionary 仍然没有通用版本,因为它是在 .NET2.0 中引入的......也许没有足够的人声称它有用......
猜你喜欢
  • 1970-01-01
  • 2021-03-20
  • 1970-01-01
  • 2017-04-18
  • 2017-04-05
  • 2018-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多