Предоставляет ли List <T> порядок вставки?

Скажем, у меня есть 3 строки в списке (например, "1", "2" , "3" ).

Затем я хочу изменить порядок их размещения "2" в позиции 1 (например, "2" , "1", "3" ).

Я использую этот код (установка indexToMoveTo в 1):

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

Это похоже на работу, но я иногда получаю странные результаты; иногда порядок неправильный или элементы из списка удаляются!

Любые идеи? Гарантирует ли заказ List<T>?

Связанный:

Имеет ли список <T> гарантировать, что элементы будут возвращены в том порядке, в котором они были добавлены?

Ответ 1

Класс List<> гарантирует упорядочение - вещи будут сохранены в списке в том порядке, в котором вы их добавляете, включая дубликаты, если вы явно не сортируете список.

Согласно MSDN:

... List "Представляет строго типизированный список объектов, к которым можно получить доступ по индексу."

Значения индекса должны оставаться надежными, чтобы это было точным. Поэтому заказ гарантирован.

Вы можете получать нечетные результаты из своего кода, если вы перемещаете элемент позже в списке, так как ваш Remove() переместит все остальные элементы на одно место перед вызовом Insert().

Можете ли вы сварить свой код до чего-то достаточно малого, чтобы опубликовать его?

Ответ 2

Вот 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), если это применимо к вашей ситуации.

Ответ 3

Как сказал Беван, но имейте в виду, что индекс списка основан на 0. Если вы хотите переместить элемент в начало списка, вы должны вставить его в индекс 0 (не 1, как показано в вашем примере).

Ответ 4

Это код, который у меня есть для перемещения элемента вниз по одному месту в списке:

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, поэтому он должен вести себя одинаково. Помогает ли это?

Конечно, первый работает только в том случае, если выбранный элемент не является последним элементом в списке, а последний, если выбранный элемент не является первым элементом.

Ответ 5

Если вы измените порядок операций, вы избежите странного поведения: Сначала вставьте значение в нужное место в списке, а затем удалите его из своей первой позиции. Убедитесь, что вы удалили его по его индексу, потому что если вы удалите его по ссылке, вы можете удалить их оба...