Как лучше всего удалить элементы списка в цикле в C#
данный код:
var AllItems = new List<CartItem>();
using(var db = new MainContext())
{
foreach (var item in AllItems)
{
if (!db.tblStoreItems.Where(i => i.ID == item.ItemID).Any())
{
AllItems.Remove(item);
}
}
}
Это лучший способ удалить элемент из объекта списка в цикле?
3 ответов
есть несколько вещей, которые неправильны с циклическим подходом, главное - вы не можете удалить элементы из коллекции, которую вы в настоящее время повторяете с foreach
- вы получите исключение.
так как ваша основная коллекция является List<T>
, вы должны использовать RemoveAll
метод, который принимает предикат. Вы также должны упростить свой запрос следующим образом:
AllItems.RemoveAll(item => !db.tblStoreItems.Any(i => i.ID == item.ItemID));
Я так не думаю. Если удалить элемент из списка, по которому выполняется итерация, результаты будут неверными.
лучше всего использовать старую моду для-loop в обратном порядке
using(var db = new MainContext())
{
for(int x = AllItems.Count - 1; x >= 0; x--)
{
var item = AllItems[x];
if (!db.tblStoreItems.Where(i => i.ID == item.ItemID).Any())
{
AllItems.RemoveAt(x);
}
}
}
это неправильно (подход OP), как справедливо предложил Стив (путь Стива, вероятно, лучший с точки зрения производительности),
Я предпочитаю хранить 'those to be removed'
в отдельный список, то вы можете сделать, например,
AllItems = AllItems.Except(Items2Remove);
это не лучший способ производительности, но для меня делает вещи чище - вы также можете объединить с перечислением LINQ-например, сделать IEnumerable из списка записей и т. д.
надеюсь, что это помогает EDIT: просто уточнить в соответствии со Стивом ответ