Гарантирует ли List <T>порядок ввода? - PullRequest
220 голосов
/ 25 июня 2009

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

Затем я хочу изменить их порядок, чтобы поместить «2» в положение 1 (например, «2», «1», «3»).

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

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

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

Есть идеи? List<T> гарантирует заказ?

Связанный:

Гарантирует ли Список , что товары будут возвращены в порядке их добавления?

Ответы [ 5 ]

287 голосов
/ 25 июня 2009

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

По данным MSDN:

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

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

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

Можете ли вы свести ваш код к чему-то достаточно маленькому для публикации?

34 голосов
/ 25 июня 2009

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

9 голосов
/ 25 июня 2009

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

1 голос
/ 06 августа 2014

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

1 голос
/ 25 июня 2009

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...