Насамперед: термінологія. Якщо ви скажете "список сміття", люди подумають, що ви говорите про сміттєзбірник. Назвемо це "списком мертвих".
Як ви, напевно, виявили, звідси і ваше запитання, ви не можете видалити елементи з колекції, поки ви повторюєте її. Якщо ваша колекція - це List<>
найпростіший спосіб видалення з неї:
for(int i = list.Count-1; i >= 0; --i)
{
if(list[i].IsDead)
list.RemoveAt(i);
}
Зауважте, що ви повторюєте назад . Ви можете видаляти елементи під час ітерації вперед, але це швидше і потрібно goto
. Ви не можете це зробити foreach
.
Ви можете зробити видалення окремо від циклу оновлення. Або ви можете об'єднати його у циклі оновлення. Завжди робити це RemoveAt
в кінці циклу - після цього точка в циклі list[i]
не може вважатися дійсною (вона знову стає дійсною при наступній ітерації).
Зауважте також, що у кожного об’єкта є власний IsDead
прапор (якщо ви використовуєте шаблон розпорядження, ви могли це зробити IsDisposed
) - насправді взагалі не потрібно підтримувати "список мертвих".
Використання прапора на кожному елементі є кращим для продуктивності, оскільки вам не доведеться шукати список, щоб зробити його видаленням. І це також краще для дизайну - це означає, що кожен об'єкт може легко перевірити, чи він мертвий, - тому ви випадково не викликаєте жодних методів на ньому (якщо ці об'єкти реалізують одноразовий зразок, вони можуть кинутись ObjectDisposedException
у цьому випадку).
Якщо у вас є інша колекція, ніж List<>
видалення мертвих предметів із цієї колекції все ще може спричинити створення списку мертвих (оскільки видалення під час ітерації може бути неможливим). На мою думку, приємніше створити список мертвих безпосередньо перед його використанням шляхом повторення колекції, шукаючи IsDead
прапори, а не намагаючись підтримувати список, коли об’єкти вбиваються.
Після того як ви закінчите зі списком мертвих, ви повинні Clear()
його, а потім зберегти його, щоб потім його повторно використовувати.