C# List<T> 是否保证插入顺序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1043039/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 06:50:32  来源:igfitidea点击:

Does List<T> guarantee insertion order?

c#.netcollections

提问by SuperSuperDev1234

Say I have 3 strings in a List (e.g. "1","2","3").

假设我在一个列表中有 3 个字符串(例如“1”、“2”、“3”)。

Then I want to reorder them to place "2" in position 1 (e.g. "2","1","3").

然后我想重新排序它们以将“2”放在位置 1(例如“2”、“1”、“3”)。

I am using this code (setting indexToMoveTo to 1):

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

listInstance.Remove(itemToMove);
listInstance.Insert(indexToMoveTo, itemToMove);

This seems to work, but I am occasionally getting strange results; sometimes the order is incorrect or items from the list are getting deleted!

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

Any ideas? Does List<T>guarantee order?

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

Related:

有关的:

Does a List<T> guarantee that items will be returned in the order they were added?

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

采纳答案by Bevan

The List<>class does guarantee ordering - things will be retained in the list in the order you add them, including duplicates, unless you explicitly sort the list.

List<>类不保证排序-事情会在包括重复添加它们,顺序列表被保留,除非你明确地分类列表。

According to MSDN:

根据 MSDN:

...List "Represents a strongly typed list of objects that can be accessed by index."

...List “表示可以通过 index访问的强类型对象列表。”

The index values must remain reliable for this to be accurate. Therefore the order is guaranteed.

索引值必须保持可靠才能准确。因此订单是有保证的。

You might be getting odd results from your code if you're moving the item later in the list, as your Remove()will move all of the other items down one place before the call to Insert().

如果您在列表的后面移动项目,您可能会从代码中得到奇怪的结果,因为Remove()在调用Insert().

Can you boil your code down to something small enough to post?

你能把你的代码简化成足够小的东西来发布吗?

回答by M4N

As Bevan said, but keep in mind, that the list-index is 0-based. If you want to move an element to the front of the list, you have to insert it at index 0 (not 1 as shown in your example).

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

回答by ChrisF

This is the code I have for moving an item down one place in a list:

这是我用于将项目在列表中向下移动一个位置的代码:

if (this.folderImages.SelectedIndex > -1 && this.folderImages.SelectedIndex < this.folderImages.Items.Count - 1)
{
    string imageName = this.folderImages.SelectedItem as string;
    int index = this.folderImages.SelectedIndex;

    this.folderImages.Items.RemoveAt(index);
    this.folderImages.Items.Insert(index + 1, imageName);
    this.folderImages.SelectedIndex = index + 1;
 }

and this for moving it one place up:

这是为了将其向上移动一个位置:

if (this.folderImages.SelectedIndex > 0)
{
    string imageName = this.folderImages.SelectedItem as string;
    int index = this.folderImages.SelectedIndex;

    this.folderImages.Items.RemoveAt(index);
    this.folderImages.Items.Insert(index - 1, imageName);
    this.folderImages.SelectedIndex = index - 1;
}

folderImagesis a ListBoxof course so the list is a ListBox.ObjectCollection, not a List<T>, but it does inherit from IListso it should behave the same. Does this help?

folderImages是 a ListBox,所以列表是 a ListBox.ObjectCollection,而不是 a List<T>,但它确实继承自,IList所以它的行为应该相同。这有帮助吗?

Of course the former only works if the selected item is not the last item in the list and the latter if the selected item is not the first item.

当然,前者仅在所选项目不是列表中的最后一个项目时才有效,后者在所选项目不是第一个项目时才有效。

回答by Joel Goodwin

Here are 4 items, with their index

这里有 4 个项目,以及它们的索引

0  1  2  3
K  C  A  E

You want to move K to between A and E -- you might think position 3. You have be careful about your indexing here, because after the remove, all the indexes get updated.

您想将 K 移动到 A 和 E 之间——您可能会想到位置 3。您在这里的索引编制要小心,因为在删除之后,所有索引都会更新。

So you remove item 0 first, leaving

所以你先删除项目 0,离开

0  1  2
C  A  E

Then you insert at 3

然后你在 3 处插入

0  1  2  3
C  A  E  K

To get the correct result, you should have used index 2. To make things consistent, you will need to send to (indexToMoveTo-1) if indexToMoveTo > indexToMove, e.g.

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

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

This may be related to your problem. Note my code is untested!

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

EDIT: Alternatively, you could Sortwith a custom comparer (IComparer) if that's applicable to your situation.

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

回答by Asaf

If you will change the order of operations, you will avoid the strange behavior: First insert the value to the right place in the list, and then delete it from his first position. Make sure you delete it by his index, because if you will delete it by reference, you might delete them both...

如果你会改变操作的顺序,你会避免奇怪的行为:首先将值插入到列表中的正确位置,然后从他的第一个位置删除它。确保你通过他的索引删除它,因为如果你通过引用删除它,你可能会同时删除它们......