List <t>是否保证插入顺序?</t>

时间:2009-06-25 10:05:23

标签: c# .net collections

说我在列表中有3个字符串(例如“1”,“2”,“3”)。

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

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

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

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

有什么想法吗? List<T>是否保证订单?

相关:

  

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

5 个答案:

答案 0 :(得分:283)

List<>类确实保证了排序 - 除非您明确对列表进行排序,否则事物将按照添加顺序保留在列表中,包括重复项。

根据MSDN:

  

... List“表示可以是强类型的对象列表   访问按索引。“

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

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

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

答案 1 :(得分:33)

以下是4项,其索引为

0  1  2  3
K  C  A  E

你想把K移到A和E之间 - 你可能会想到位置3.你在这里注意你的索引,因为在删除之后,所有的索引都会被更新。

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

0  1  2
C  A  E

然后你插入3

0  1  2  3
C  A  E  K

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

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

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

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

答案 2 :(得分:9)

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

答案 3 :(得分:1)

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

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;
 }

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

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;
}

folderImages当然是ListBox,所以列表是ListBox.ObjectCollection,而不是List<T>,但它确实从IList继承,所以它应该表现得很好相同。这有帮助吗?

当然前者只有在所选项目不是列表中的最后一项时才有效,而后者如果所选项目不是第一项则是后者。

答案 4 :(得分:1)

如果您要更改操作顺序,您将避免这种奇怪的行为: 首先将值插入列表中的正确位置,然后将其从第一个位置删除。确保你通过索引删除它,因为如果你通过引用删除它,你可以删除它们......