8

I have a list containing some objects and want to use LINQ to remove a specific item but am not sure how to do that.

foreach (var someobject in objectList)
{
    if (someobject.Number == 1) // There will only one item where Number == 1.  
    {
        list.remove(someobject)
    } 
}
J0e3gan
  • 8,740
  • 10
  • 53
  • 80
Lynct
  • 201
  • 1
  • 4
  • 10

4 Answers4

29

You cannot use a foreach to remove items during enumeration, you're getting an exception at runtime.

You could use List.RemoveAll:

list.RemoveAll(x => x.Number == 1);

or, if it's actually not a List<T> but any sequence, LINQ:

list = list.Where(x => x.Number != 1).ToList();

If you are sure that there is only one item with that number or you want to remove one item at the maximum you can either use the for loop approach suggested in the other answer or this:

var item = list.FirstOrDefault(x => x.Number == 1);
if(item ! = null) list.Remove(item);

The link to the other question i have posted suggests that you can modify a collection during enumeration in C# 4 and later. No, you can't. That applies only to the new concurrent collections.

Community
  • 1
  • 1
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • 2
    In this case you could actually use a foreach since there's only one item to remove. Just make sure to use break to go out of the loop after the item has been removed, otherwise you'll get an exception on the next iteration. That said, I think the solution with RemoveAll() is more elegant. – haagel Nov 17 '17 at 10:53
4

You can't use foreach to remove item from collection. This will throw an exception that the collection is modified.

You can perform it with for

for (int i=objectList.Count-1; i>=0 ; i--)
{
    if (objectList[i].Number == 1) // there will only one item with Number = 1   
    {
       objectList.Remove(objectList[i]);
    } 
}

Other case is to use Remove/RemoveAll like Tim Schmelter show.

mybirthname
  • 17,949
  • 3
  • 31
  • 55
  • As pointed out elsewhere, if you're happy to `break` after you find a match, there's no reason to switch the `foreach` loop to a `for` loop. – Rawling Jan 05 '18 at 07:48
  • 1
    @Rawling some other guy added the break statement. Anyway, the answer at the beginning was not good too. – mybirthname Jan 05 '18 at 16:28
2

You CAN use a foreach loop to remove an item from a list. The important thing is to use break to stop the loop once you have removed the item. If the loop continues after an item is removed from the list, an exception will be thrown.

foreach (var someobject in objectList)
{
    if (someobject.Number == 1) // There will only one item where Number == 1
    {
        objectList.remove(someobject);
        break;
    } 
}

However, this will ONLY work if there's only one object you want to remove, as in your case.

haagel
  • 2,646
  • 10
  • 36
  • 53
-1

you could remove at the index if the value meets the criteria

for (int i=0; i < objectList.Count; i ++)
{
    if (objectList[i].Number == 1) // there will only one item with Number = 1   
    {
       objectList.RemoveAt[i];
    } 
}
SuncoastOwner
  • 263
  • 2
  • 9