web-dev-qa-db-fra.com

List <T> garantit-il l'ordre d'insertion?

Supposons que j'ai 3 chaînes dans une liste (par exemple, "1", "2", "3").

Ensuite, je souhaite les réorganiser pour placer "2" en position 1 (par exemple, "2", "1", "3").

J'utilise ce code (paramètre indexToMoveTo à 1):

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

Cela semble fonctionner, mais j'obtiens parfois des résultats étranges. Parfois, la commande est incorrecte ou les éléments de la liste sont supprimés!

Des idées? Est-ce que List<T> ordre de garantie?

Apparenté, relié, connexe:

ne liste <T> garantit-elle que les articles seront retournés dans l'ordre dans lequel ils ont été ajoutés?

221
SuperSuperDev1234

La classe List<> garantit la commande; les éléments seront conservés dans la liste dans l'ordre dans lequel vous les ajoutez, y compris les doublons, à moins que vous ne triiez explicitement la liste.

Selon MSDN:

... List "Représente une liste fortement typée d'objets accessibles par index ."

Les valeurs d'index doivent rester fiables pour que cela soit précis. Par conséquent, la commande est garantie.

Vous pourriez obtenir des résultats étranges à partir de votre code si vous déplacez l'élément plus tard dans la liste, car votre Remove() déplacera tous les autres éléments d'un endroit avant l'appel à Insert() .

Pouvez-vous réduire votre code à quelque chose d'assez petit pour poster?

288
Bevan

Voici 4 articles, avec leur index

0  1  2  3
K  C  A  E

Vous voulez déplacer K entre A et E - vous pourriez penser à la position 3. Vous devez faire attention à votre index ici, car après la suppression, tous les index sont mis à jour.

Donc, vous supprimez le premier élément en laissant

0  1  2
C  A  E

Ensuite, vous insérez à 3

0  1  2  3
C  A  E  K

Pour obtenir le résultat correct, vous devez avoir utilisé index 2. Pour rendre les choses cohérentes, vous devrez envoyer à (indexToMoveTo-1) if indexToMoveTo > indexToMove, par exemple.

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

Cela peut être lié à votre problème. Notez que mon code n'a pas été testé!

EDIT : Vous pouvez également Sort avec un comparateur personnalisé (IComparer) si cela s'applique à votre situation.

34
Joel Goodwin

Comme Bevan l'a dit, mais rappelez-vous, l'index de liste est basé sur 0. Si vous souhaitez déplacer un élément au début de la liste, vous devez l'insérer à l'index 0 (et non 1 comme indiqué dans votre exemple).

9
M4N

Si vous changez l'ordre des opérations, vous éviterez le comportement étrange: insérez d'abord la valeur au bon endroit dans la liste, puis supprimez-la de sa première position. Assurez-vous de le supprimer par son index, car si vous le supprimiez par référence, vous pourriez les supprimer tous les deux ...

1
Asaf

C'est le code que j'ai pour déplacer un élément d'une place dans la liste:

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

et ceci pour le déplacer d'un endroit vers le haut:

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 est un ListBox bien sûr, donc la liste est un ListBox.ObjectCollection, pas un List<T>, mais il hérite de IList alors il devrait se comporter de la même manière. est-ce que cela aide?

Bien sûr, le premier ne fonctionne que si l'élément sélectionné n'est pas le dernier élément de la liste et le dernier si l'élément sélectionné n'est pas le premier.

1
ChrisF