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

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

我正在使用这段代码(设置indexToMoveTo为1):

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

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

什么好主意吗?List<T>是否保证有序?

相关:

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


当前回答

List<>类确实保证了排序——除非显式地对列表进行排序,否则列表中的内容将按照您添加它们的顺序保留,包括重复项。

根据MSDN:

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

指标值必须保持可靠,这是准确的。因此订单是有保证的。

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

你能把你的代码精简到可以发布的程度吗?

其他回答

以下是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)如果indexToMoveTo > indexToMove,例如。

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

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

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

这是我在列表中向下移动一项的代码:

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,所以它的行为应该是一样的。这有用吗?

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

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

List<>类确实保证了排序——除非显式地对列表进行排序,否则列表中的内容将按照您添加它们的顺序保留,包括重复项。

根据MSDN:

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

指标值必须保持可靠,这是准确的。因此订单是有保证的。

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

你能把你的代码精简到可以发布的程度吗?

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