我知道关于HashSet
和订单保留存在几个问题,非常简单的测试表明,如果添加和删除项目,则根本不会保留订单。
但是我的问题与是否从HashSet
删除项目是否保留插入顺序有关。
早在2009年,乔恩·斯基特(https://stackoverflow.com/a/657289/10894153)说:
如果您从不删除任何项目,则可能会保留插入顺序。我不确定,但是我不会完全感到惊讶。
他当时认为:
我没有研究内部结构或源代码(显然我没有)。
显然,这已经发生了变化,并且.NET现在是开源的,我想知道是否有人可以确定地验证插入顺序是否确实在没有删除任何项目的情况下保留在HashSet
上。
在问这个问题之前,我已经进行了几次 quick 测试,向HashSet
中添加了1000个项目,并且保留了插入顺序,但这绝不能证明它会即使没有删除也总是如此。
编辑
如HimBromBeere所指出的,HashSet
的官方文档指出,该顺序未保留,因此即使当前的实现得以维持(尽管很明显他们确实不对此保证)。插入顺序,将来可能会更改。
话虽如此,但我对当前实现中没有删除的情况下是否保持插入顺序感兴趣(.NET 4.7.2)
答案 0 :(得分:1)
话虽如此,我对插入顺序是否 在当前实现中没有删除时保持不变。
是的,它保留在4.7.2中。截至2019年1月18日。
我怀疑这里的部分问题是了解合同与实施之间的区别。
4.7.2中HashSet
的实现将保持插入顺序(如果您不删除项目)。但是您最初并没有这样问。您问是否:
保证插入顺序
对于这个问题,答案无疑是不。方法的保证不是由实现定义的,而是由合同定义的。 contract指出:
集合是不包含重复元素的集合,其集合 元素没有特殊顺序。
除了没有保证订购外,根本无法以任何其他方式读取该声明。
现在-您可以选择忽略保证,并根据当前行为部署应用程序。而且,只要Microsoft不发布会更改行为的Windows Update补丁(或者您的代码在Mono等类似的不同实现中运行),您就可能没问题。但是可能和绝对(或保证的)不同。