C# 为什么.Net字典看起来像是已排序的?

C# 为什么.Net字典看起来像是已排序的?,c#,.net,sorting,dictionary,hashtable,C#,.net,Sorting,Dictionary,Hashtable,我正在看同事签入的一些代码,看起来是这样的: return list.OrderBy(item => item.Order).ToDictionary(item => item.Id); 我立即告诉我的同事,他的代码是错误的,因为字典是一个哈希表,一个未排序的集合。我说,他要么使用保留顺序的集合,要么在以后使用foreach从字典中读取条目时对其进行排序 但是他回答说:“不,不,我的代码是正确的!看:现在我已经添加了OrderBy,这些项目以正确的顺序出现。” 事实证明,在测试案例

我正在看同事签入的一些代码,看起来是这样的:

return list.OrderBy(item => item.Order).ToDictionary(item => item.Id);
我立即告诉我的同事,他的代码是错误的,因为
字典
是一个哈希表,一个未排序的集合。我说,他要么使用保留顺序的集合,要么在以后使用
foreach
从字典中读取条目时对其进行排序

但是他回答说:“不,不,我的代码是正确的!看:现在我已经添加了
OrderBy
,这些项目以正确的顺序出现。”

事实证明,在测试案例中,他是对的。我尝试了一些其他数据,但它仍然是完美的排序

我告诉他不应该依赖这种行为,但他不同意,我很难解释原因。除此之外,我很感兴趣的是为什么这个秩序经常被保留下来


所以我的问题是。。。为什么
字典
(一个基本上未排序的集合)看起来像是已排序的呢?

当在字典上迭代时,您会将其中的项目放入

在本例中,对列表进行排序,然后依次将每个项添加到字典中

最终的结果是字典中的项按列表的排序顺序排列

然而,对于当前的
字典的实现来说,情况恰好是这样的-不能保证它会保持这种状态


如果您需要将
词典中的项按特定顺序排列,则应使用。

对其进行排序,因为
词典
是如何实现的(在您的情况下,项是按顺序添加的)。但这是实施细节


告诉你的同事存在一个类,这应该让他相信我们不能依靠简单的
字典
;)来确定项目顺序

字典不能保证集合是无序的。它不是故意使用随机的。是的,密码错了。是的,贾斯汀,这是一个副本。你链接的问题的答案就是我想要的。在这么多关于词典的问题中,你怎么能这么快找到重复的?我找了又找不到。非常感谢。我不知道(这就是为什么我将此作为注释发布),但我认为它与SQL中的相同:由
SELECT
返回的行以未指定的顺序返回,除非包含
orderby
子句。通常,尤其是在小数据集中,返回的行与插入的行的顺序相同,这会让很多人大吃一惊。(我总是告诉人们,如果他们关心结果的顺序,就要包含一个
orderby
。如果没有它,它可能会起作用,但也可能会坏得很厉害。)@eldritchcondurum——这是谷歌上
.net字典顺序的第一个结果。我发现谷歌有时比内置搜索更有效。你能更好地解释为什么它们会被分类吗。我会说它们是由hash属性“Id”@LuisFilipe“排序”的——我不明白。列表已排序(
list.OrderBy(item=>item.Order)
然后转换为一个
Dictionary
。转换通过将每个项添加到Dictionary中来实现。Dictionary中的项是“有序的”因为它们是按插入顺序插入的。因为它们是按顺序插入的,所以字典是按顺序插入的。这是由规范/契约保证的,还是具体实现的编写方式的产物?如果是有保证的行为,引用将是有用的。@MichaelKjörling-没有保证,这只是当前版本的编写方式实现了字典的
。Luis,实际上键是以散列依赖顺序存储的,但值不是,字典枚举器使用值存储。这是一个实现细节,当然,但我认为它不会改变。也许可以说Add()-只有字典才能保持顺序。@Eldritchcondrum真的,你不应该这么认为。目前是这样,但在未来的版本中可能不是。想想框架的其他实现(例如Mono)是的。更重要的是,现在我知道如何构建一个测试用例,我的同事的代码将失败;)我只需要在foreach之前删除和添加。