0

Scenario

I have a system that holds races, each race has a unique list of members on that race. (the list is a List< T > )

I want users to be able to remove a member (if they ARE this member) from the list of members on that race.

Problem

I'm trying to get the following code to work:

foreach (string item in hillracing.searchRaces(RaceID).RaceList) // Loop through List with foreach.
{
    if (item == SelectedItem)
    {
        item = null;
    }
}

I can't edit the variable because it is in a foreach loop, how would I achieve this another way?

Method
  • 143
  • 9
  • possible duplicate of [What is the best way to modify a list in a 'foreach' loop?](http://stackoverflow.com/questions/759966/what-is-the-best-way-to-modify-a-list-in-a-foreach-loop) – Liam May 19 '15 at 10:49
  • I think @Nils O suggestion that if you have `SelectedItem` already, you can just call the list's `Remove` method is what you are looking for. You should mark that as the answer. – amcdermott May 19 '15 at 11:07

5 Answers5

1

You can just store it and remove it form the collection afterwards.

var toRemove = null;
foreach (string item in hillracing.searchRaces(RaceID).RaceList) // Loop through List with foreach.
{
    if (item == SelectedItem)
    {
        toRemove = item;
        break; //Can break here if you're sure there's only one SelectedItem
    }
}
hillracing.searchRaces(RaceID).Racelist.Remove(toRemove);

though in this case you could also just use hillracing.searchRaces(RaceID).Racelist.Remove(SelectedItem); and you won't use the foreach loop at all.

Nils O
  • 1,321
  • 9
  • 19
  • Upvoting this - think the previous down vote was, to say the least, daft. Also, you spotted that if the OP already has a handle on `SelectedItem` he/she should be able to call `Remove` on it without needing to loop through anything - which is the most efficient approach listed here. – amcdermott May 19 '15 at 11:06
0

You can't do that in a foreach loop. If it's an IList/IList<T> which allows random access, like an array or list, you can use a for-loop:

List<string> = hillracing.searchRaces(RaceID).RaceList;
for(int i = 0; i < list.Count; i++)
{
    if(list[i] == SelectedItem)
         list[i] = null;
}

So you can't add or remove items in the foreach but you also can't replace the reference. The object refers to the original value so you could modify the object(if strings werent immutable) but you can't replace the reference itself in a foreach. This is related.

Community
  • 1
  • 1
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
0

You can't modify collection that you are looping using foreach loop. The collection used in foreach is immutable. This is by design.

The foreach statement is used to iterate through the collection to get the information that you want, but can not be used to add or remove items from the source collection to avoid unpredictable side effects. If you need to add or remove items from the source collection, use a for loop.

Rahul Nikate
  • 6,192
  • 5
  • 42
  • 54
0

Using Linq you shouldn't need to loop to find the entry you want to nullify...

// Use of Single() here assumes the object definitely exists. 
// Use SingleOrDefaul() if there is a chance it might not exist.
var item = hillracing.searchRaces(RaceID)
                     .RaceList
                     .Where(x => x.Item == SelectedItem).Single();  

item = null;

Edit: Since you've changed the requirement to remove the item from the list, I think you'd just call the Remove method`with the found item. So the code becomes

// Use of Single() here assumes the object definitely exists. 
// Use SingleOrDefaul() if there is a chance it might not exist.
var item = hillracing.searchRaces(RaceID)
                     .RaceList
                     .Where(x => x.Item == SelectedItem).Single();  

hillracing.searchRaces(RaceID).RaceList.Remove(item);
amcdermott
  • 1,565
  • 15
  • 23
0

Use the existing Remove()-method to search and remove the item for you:

hillracing.searchRaces(RaceID).RaceList.Remove(SelectedItem);

W0lfw00ds
  • 2,018
  • 14
  • 23