List <T>是否保证插入订单?

Sup*_*234 225 .net c# collections

假设我在列表中有3个字符串(例如"1","2","3").

然后我想重新排序它们将"2"放在位置1(例如"2","1","3").

我正在使用此代码(将indexToMoveTo设置为1):

listInstance.Remove(itemToMove);
listInstance.Insert(indexToMoveTo, itemToMove);
Run Code Online (Sandbox Code Playgroud)

这似乎有效,但我偶尔会得到奇怪的结果; 有时订单不正确或列表中的项目被删除!

有任何想法吗?并List<T>保证订单?

有关:

List <T>是否保证项目按照添加顺序返回?

Bev*_*van 292

List<>类不保证排序-事情会在你添加它们,包括重复,除非你明确地对列表进行排序的顺序列表中保留.

根据MSDN:

... List"表示可以通过索引访问的强类型对象列表."

索引值必须保持可靠,以确保准确.因此订单得到保证.

如果您稍后在列表中移动项目,则可能会从代码中获得奇怪的结果,因为您Remove()将在调用之前将所有其他项目移动到一个位置Insert().

你可以将你的代码煮到足够小的东西发布吗?

  • 对于任何未来的googler,这里是来自MSDN(bolding mine)的[List(T).Add](http://msdn.microsoft.com/en-us/library/3wcytfd1.aspx)的确切引用_对象是添加到List <T>的**结尾**.对于引用类型,该值可以为null ._ (60认同)
  • 我们可以从微软或C#规范中获得更明确的引用/参考吗?@ aolszowka的引用肯定似乎暗示它确实保留了插入顺序,但从技术上讲,List可以在添加项目之后的任何时候重新排序集合,并且该声明仍然有效.我不想对此不屑一顾,但如果一位经理或QA真的让我捍卫这个位置,我对这句话我不会感到非常自信. (4认同)
  • 我可以想出两种有用的方法来获得一些确认.首先,[阅读来源](http://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs,cf7f4095e4de7646)并满足自己.其次,在任何好的计算机科学教科书中查看抽象数据类型`List`的定义.就像`Queue`和`Stack`一样,`List`是一个定义良好,可预测且易于理解的数据结构 - 如果.NET实现不同(或者如果它发生变化),那么*很多软件就会破坏. (4认同)

Joe*_*win 34

这里有4个项目及其索引

0  1  2  3
K  C  A  E
Run Code Online (Sandbox Code Playgroud)

您希望将K移动到A和E之间 - 您可能会认为位置3.您在此处注意索引,因为在删除之后,所有索引都会更新.

所以你先删除第0项,然后离开

0  1  2
C  A  E
Run Code Online (Sandbox Code Playgroud)

然后你插入3

0  1  2  3
C  A  E  K
Run Code Online (Sandbox Code Playgroud)

要获得正确的结果,您应该使用索引2.为了使事情保持一致,您需要发送到(indexToMoveTo-1)if indexToMoveTo > indexToMove,例如

bool moveUp = (listInstance.IndexOf(itemToMoveTo) > indexToMove);
listInstance.Remove(itemToMove);
listInstance.Insert(indexToMoveTo, moveUp ? (itemToMoveTo - 1) : itemToMoveTo);
Run Code Online (Sandbox Code Playgroud)

这可能与您的问题有关.请注意我的代码未经测试!

编辑:或者,您可以Sort使用自定义比较器(IComparer),如果这适用于您的情况.

  • 是的,但你已经详细阐述并给出了Bevan的答案的例子,以及一些解决方案代码,所以你的答案不是同义词,我已经投了你的票. (8认同)

M4N*_*M4N 9

正如Bevan所说,但请记住,list-index是基于0的.如果要将元素移动到列表的前面,则必须将其插入索引0(不是1,如示例所示).