Loop through ICollection and set to null

I need to remove the data from an ICollection if the ID of the collection is in a List of ID's.

What I have so far:

    foreach (var notSelectedToolId in notSelectedToolIds)
    {
        for (int i = 0; i < matchingHoleInfoVm.ToolHeader.Count; i++)
        {
            if (matchingHoleInfoVm.ToolHeader.ElementAt(i).ToolID == notSelectedToolId)
            {
                matchingHoleInfoVm.ToolHeader.ElementAt(i) = new ToolHeaderViewModel();
            }
        }
    }

The error I get: "This expression cannot be used as an assignment target".

How can I make this work?

Jon Skeet
people
quotationmark

You can't, basically - not with just ICollection (or even ICollection<T>). Neither of them allow you to replace an existing element with a new one.

With IList<T>, it's pretty easy:

var list = matchingHoleInfoVm.ToolHeader;
for (int i = 0; i < list.Count; i++)
{
    if (list[i].ToolID == notSelectedToolId)
    {
        list[i] = new ToolHeaderViewModel();
    }
}

In most cases where you've already got an ICollection<T>, you'll find it already implements IList<T>. If it doesn't, you need to look carefully at what the collection actually is, and consider whether "replace at the same index" even makes sense. (If it's a HashSet<,>, for example, you can just remove the existing item and add a new one...)

EDIT: If you only need to remove the items, you can just use the Remove method:

var itemsToRemove = collection.Where(c => c.ToolID == notSelectedToolId).ToList();
                              .ToList();
foreach (var item in itemsToRemove)
{
    collection.Remove(item);
}

Additionally, you don't need nested loops - you can use something like:

var itemsToRemove = collection.Where(c => notSelectedToolIds.Contains(c.ToolID))

to find all of the ones to remove in a single pass (then remove them as above).

people

See more on this question at Stackoverflow