Przede wszystkim: terminologia. Jeśli powiesz „lista śmieci”, ludzie pomyślą, że mówisz o śmieciarzu. Nazwijmy to „martwą listą”.
Jak zapewne odkryłeś, stąd twoje pytanie, nie możesz usuwać przedmiotów z kolekcji podczas iteracji. Jeśli Twoja kolekcja jest List<>najprostszym sposobem na usunięcie z niej przedmiotów:
for(int i = list.Count-1; i >= 0; --i)
{
if(list[i].IsDead)
list.RemoveAt(i);
}
Pamiętaj, że iterujesz wstecz . Możesz usuwać elementy podczas iteracji do przodu, ale jest to bardziej skomplikowane i wymaga goto. Nie możesz tego zrobić foreach.
Możesz wykonać usuwanie oddzielnie od pętli aktualizacji. Lub możesz połączyć go w pętlę aktualizacji. Zawsze wykonuj RemoveAtna końcu pętli - po tym punkcie w pętli list[i]nie można jej uznać za poprawną (staje się znów ważna przy następnej iteracji).
Zauważ też, że każdy obiekt ma swoją własną IsDeadflagę (jeśli używasz wzorca usuwania, możesz to zrobić IsDisposed) - tak naprawdę wcale nie musisz utrzymywać „martwej listy”.
Używanie flagi na każdym elemencie jest lepsze ze względu na wydajność, ponieważ unikasz konieczności przeszukiwania listy w celu usunięcia. Jest również preferowany przy projektowaniu - oznacza to, że każdy obiekt może łatwo sprawdzić, czy jest martwy - więc nie wywołujesz przypadkowo żadnych metod na nim (jeśli obiekty te implementują wzór jednorazowy, mogą ObjectDisposedExceptionw tym przypadku rzucić ).
Jeśli masz kolekcję inną niż a List<>, usunięcie martwych elementów z tej kolekcji może nadal wymagać utworzenia martwej listy (ponieważ usunięcie podczas iteracji może być niemożliwe). Moim zdaniem, lepiej jest zaprojektować martwą listę tuż przed jej użyciem, iterując kolekcję w poszukiwaniu IsDeadflag, zamiast starać się zachować listę, gdy obiekty są zabijane.
Gdy skończysz z martwą listą, powinieneś Clear()ją zachować, a następnie pozostawić w pobliżu, aby użyć jej później.