Wednesday, August 21, 2013

Dynamically adding or removing items from a C# collection in a loop.

Strictly speaking, there is no way to dynamically add or remove items from a Collection in a C# Foreach loop. There are at least three ways I know of that this can be faked though, do you know any others?

The "Right" Way
for(i = list.Count()-1;i>=0;i--)
{
item=list[i];
if (item.Delete) list.Remove(item);
}
This way cycles through the list backwards with a plain old For loop. Doing this forwards could be problematic if the size of the collection changes, but backwards should always be safe.

The "Easy" Way
foreach(var item in list.ToList())
{
if(item.Delete) list.Remove(item);
}
Simply create an entirely new list from the first one. I say "Easy" rather than "Right" as creating an entirely new list probably comes at a performance premium over the previous method (I haven't bothered with any benchmarking.) I generally prefer this pattern, it can also be useful in overcoming Linq-To-Entities limitations.

The "Strange" Way
var outList = new List(CustomObject);
foreach(var item in list)
{
if(!item.Delete) outList.Add(item);
}
list = outList;
I encountered this particular pattern in early versions of the Monkey programming language. Monkey originally had no way of removing items from a collection (No longer an issue), so the only way you could do it is to create a smaller list to supplant the larger one. This is probably the clumsiest and slowest of the three methods, but it has the unusual (but probably useless) advantage of not needing a remove method.

The Linq Way
list.RemoveAll(p=>p.Delete);