List< T>保证插入顺序?

假设我在一个列表中有3个字符串(例如:&;1",&;2",&;3")。

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

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

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

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

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

相关:

Does a List<T>保证项目将返回的顺序,他们被添加?< / >

137835 次浏览

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

根据MSDN:

< p >…List "表示可以为的对象的强类型列表 通过索引访问。" < / p >

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

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

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

正如Bevan所说,但是请记住,list-index是基于0的。如果想要将一个元素移动到列表的前面,则必须将其插入索引0(而不是示例中的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项,以及它们的索引

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

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

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

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