【发布时间】:2017-12-12 19:47:19
【问题描述】:
我已经阅读了官方 MSDN doc 和多个关于 Dictionary/Hashset 和其他无序集合顺序问题的 SO 问题。这个问题有点不同 - 我正在寻找实际的实际例子而不是理论
条件:
- 只能添加字典/hastable 条目
- 永远不会删除字典/hastable 条目(除非在开始时清除)
- 字典/hastable 仅使用 VALUE TYPES 运行
- 除了添加元素外,字典/hastable 永远不会以任何其他方式更改
- 字典/hastable 总是从 0 开始,并通过简单的代码逻辑保留索引
- 字典键本身(键名)永远不会手动更改
代码示例:
Dictionary<int, int> test = new Dictionary<int, int>();
for (int i = 0; i <= 100000; i++)
{
test.Add(i,i);
}
var c = 0;
while (c < test.Count)
{
if (c != test.ElementAt(c).Key)
{
Console.WriteLine("Mismatch!");
break;
}
c++;
}
Console.WriteLine("Test passed!");
//Program takes a 2hrs walk, does things, occasionally reads-only values from existing "test" collection
for (int i = 0; i <= 500000; i++)
{
test[test.Count] = test.Count;
}
c = 0;
while (c < test.Count)
{
if (c != test.ElementAt(c).Key)
{
Console.WriteLine("Mismatch!");
break;
}
c++;
}
Console.WriteLine("Test 2 passed!");
//repeat some stuff
问题: 根据上述给定的严格规则 - 有没有人真正遇到过这种字典随机更改其元素顺序的情况?我们不是一次又一次地谈论 MT 并发集合,我对理论答案不感兴趣,I've read them.
我正在寻找test.ElementAt(5).key 将返回key 为11 或115 的单个示例。
【问题讨论】:
-
Dictionary<TKey, TValue>的源代码在here 可用。如果您查看Enumerator.MoveNext(),您会看到它按顺序返回dictionary.entries。 -
如果您查看
private void Insert(TKey key, TValue value, bool add),您会发现只要没有空闲条目,添加的项目就会放在entries数组的末尾,并且重新散列不会改变这个顺序。所以看来,有了这个实现,只要什么都没有被删除,字典就会保留添加东西的顺序。 -
但这只是一个实现细节。
Dictionary<TKey, TValue>在单声道上的版本(或一些未来的 .Net 版本,比如 .Net core 3.5 或 .Net full 5.2 或无论如何)可以重写,以便重新散列字典更改顺序。 documentation 做出的唯一承诺是返回项目的顺序是不确定的,所以再依赖任何东西都是不明智的。 -
所以,鉴于您现在所说的,请告诉我这句话是否属实:
"You can rely on Dictionary order under given restrictions to solve single current task at hand right now with its current implementation".不是在谈论当 DT/HT 实施中断/更改时可能会中断的长期实施。另外,作为答案发布。
标签: c# dictionary