how properly remove item from list [duplicate]
Possible Duplicates:
Exception during iteration on collection and remove items from that collection How to remove elements from a generic list while iterating around it? Better way to remove matched items from a list
// tmpClientList is List<Client> type
if (txtboxClientName.Text != "")
foreach (Client cli in tmpClientList)
if (c开发者_JS百科li.Name != txtboxClientName.Text)
tmpClientList.Remove(cli);
Error: "Collection was modified; enumeration operation may not execute."
How can i remove items from the list, in some simple way, without saving indexes of these items in another list or array, and removing them in another place in the code. Tried also RemoveAt(index) but it's exactly the same situation, modifying when loop runs.
Move backwards through the list.. that way removing an item does not affect the next item.
for(var i=tmpClientList.Count-1;i>=0;i--)
{
if (tmpClientList[i].Name != txtboxClientName.Text)
tmpClientList.RemoveAt(i);
}
On a List<T>
, there is a RemoveAll
method that takes a delegate to indicate whether to remove the item. You can use it like this:
tmpCLientList.RemoveAll(cli => cli.Name != txtboxClientName.Text);
Either use a for/while loop, or tmpClientList.RemoveAll(a => a.Name == txtboxClientName.Text)
. As you didn't specify which c# version you are using, ymmw.
Don't use foreach. Use for and descend the list (i.e. start from the end), using RemoveAt.
So,
// tmpClientList is List<Client> type
if (txtboxClientName.Text != "")
foreach (int pos = tmpClientList.Length - 1; pos >= 0; pos--)
{
Client cli = tmpClientList[pos];
if (cli.Name != txtboxClientName.Text)
tmpClientList.RemoveAt(pos);
}
The problem is that you are trying the modify the list in a foreach iteration. Replace that with a for and you should be ok.
Also, since you seem to be using user input for the name, consider cleaning up the input a bit, at least with a Trim() to remove extra white spaces. If you don't, 'John ' and 'John' will be two different things. Same for the initial != "" check.
You can create another list with the items you want to delete and iterate the new list to remove items from your "txtboxClientName" list.
Actually, foreach uses Enumerators to iterate through given Item-Collections. Going further the System.Collections.Generic.List<T>
implements the IEnumarable
-Interface to provide a Class, that knows how to iterate through the items of the list, i.e. the Enumerator. Now if you iterate through that list by using foreach the Enumerator keeps track of the current position, how to reach the next position and some other stuff. The internal logic could be something like storing the number of items in a variable n and then access all objects from 0 to n-1. As you may notice if any object is removed between the iteration steps we shall end in a NullReferenceException
when the Enumerator tries to deliver the last object of the list. So to prevent any iteration failures, the list itself is not allowed to be modified during Enumeration.
Hope I was able to state that out at least a little bit comprehensively. :-)
精彩评论