If you must transfer from one list to another here is the fasted result I've found:
var filtered = new List<SomeClass>(allItems); for (int i = 0; i < filtered.Count; i++) if (filtered[i].id == 9999) filtered.RemoveAt(i);
I tried comparing your method, the method above, and a linq "where" statement:
var allItems = new List<SomeClass>(); for (int i = 0; i < 10000000; i++) allItems.Add(new SomeClass() { id = i }); Console.WriteLine("Tests Started"); var timer = new Stopwatch(); timer.Start(); var filtered = new List<SomeClass>(); foreach (var item in allItems) if (item.id != 9999) filtered.Add(item); var y = filtered.Last(); timer.Stop(); Console.WriteLine("Transfer to filtered list: {0}", timer.Elapsed.TotalMilliseconds); timer.Reset(); timer.Start(); filtered = new List<SomeClass>(allItems); for (int i = 0; i < filtered.Count; i++) if (filtered[i].id == 9999) filtered.RemoveAt(i); var s = filtered.Last(); timer.Stop(); Console.WriteLine("Removal from filtered list: {0}", timer.Elapsed.TotalMilliseconds); timer.Reset(); timer.Start(); var linqresults = allItems.Where(x => (x.id != 9999)); var m = linqresults.Last(); timer.Stop(); Console.WriteLine("linq list: {0}", timer.Elapsed.TotalMilliseconds);
The results were as follows: Tests Started
Transfer to filtered list: 610.5473
Removal from filtered list: 207.5675
linq list: 379.4382
using the "Add(someCollection)" and using a ".RemoveAt" was a good deal faster.
Also, subsequent .RemoveAt calls are pretty cheap.