C# 集合被修改;枚举操作可能不会在 ArrayList 中执行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2024179/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Collection was modified; enumeration operation may not execute in ArrayList
提问by Ricardo
I'm trying to remove an item from an ArrayList
and I get this Exception:Collection was modified; enumeration operation may not execute.
我正在尝试从 an 中删除一个项目,但出现ArrayList
此异常:Collection was modified; enumeration operation may not execute.
Any ideas?
有任何想法吗?
采纳答案by Marc Gravell
You are removing the item during a foreach
, yes? Simply, you can't. There are a few common options here:
您是在 a 期间删除该项目foreach
,是吗?简单地说,你不能。这里有一些常见的选项:
- use
List<T>
andRemoveAll
with a predicate iterate backwards by index, removing matching items
for(int i = list.Count - 1; i >= 0; i--) { if({some test}) list.RemoveAt(i); }
use
foreach
, and put matching items into a second list; now enumerate the second list and remove those items from the first (if you see what I mean)
- 使用
List<T>
和RemoveAll
带谓词 按索引向后迭代,删除匹配项
for(int i = list.Count - 1; i >= 0; i--) { if({some test}) list.RemoveAt(i); }
使用
foreach
,并将匹配的项目放入第二个列表中;现在枚举第二个列表并从第一个列表中删除这些项目(如果你明白我的意思)
回答by 3Dave
Don't modify the list inside of a loop which iterates through the list.
不要在遍历列表的循环内修改列表。
Instead, use a for()
or while()
with an index, going backwards through the list. (This will let you delete things without getting an invalid index.)
相反,使用带有索引的for()
或while()
,向后遍历列表。(这将使您可以删除内容而不会获得无效索引。)
var foo = new List<Bar>();
for(int i = foo.Count-1; i >= 0; --i)
{
var item = foo[i];
// do something with item
}
回答by Seva Alekseyev
Instead of foreach(), use a for() loop with a numeric index.
使用带有数字索引的 for() 循环代替 foreach()。
回答by ozczecho
One way is to add the item(s) to be deleted to a new list. Then go through and delete those items.
一种方法是将要删除的项目添加到新列表中。然后通过并删除这些项目。
回答by Will
Here's an example (sorry for any typos)
这是一个例子(抱歉有任何错别字)
var itemsToRemove = new ArrayList(); // should use generic List if you can
foreach (var item in originalArrayList) {
if (...) {
itemsToRemove.Add(item);
}
}
foreach (var item in itemsToRemove) {
originalArrayList.Remove(item);
}
OR if you're using 3.5, Linq makes the first bit easier:
或者,如果您使用的是 3.5,Linq 会使第一个更容易:
itemsToRemove = originalArrayList
.Where(item => ...)
.ToArray();
foreach (var item in itemsToRemove) {
originalArrayList.Remove(item);
}
Replace "..." with your condition that determines if item should be removed.
将“...”替换为确定是否应删除项目的条件。
回答by Joe B
I like to iterate backward using a for
loop, but this can get tedious compared to foreach
. One solution I like is to create an enumerator that traverses the list backward. You can implement this as an extension method on ArrayList
or List<T>
. The implementation for ArrayList
is below.
我喜欢使用循环向后迭代for
,但这与foreach
. 我喜欢的一种解决方案是创建一个向后遍历列表的枚举器。您可以将其实现为ArrayList
或上的扩展方法List<T>
。的实现ArrayList
如下。
public static IEnumerable GetRemoveSafeEnumerator(this ArrayList list)
{
for (int i = list.Count - 1; i >= 0; i--)
{
// Reset the value of i if it is invalid.
// This occurs when more than one item
// is removed from the list during the enumeration.
if (i >= list.Count)
{
if (list.Count == 0)
yield break;
i = list.Count - 1;
}
yield return list[i];
}
}
The implementation for List<T>
is similar.
的实现List<T>
类似。
public static IEnumerable<T> GetRemoveSafeEnumerator<T>(this List<T> list)
{
for (int i = list.Count - 1; i >= 0; i--)
{
// Reset the value of i if it is invalid.
// This occurs when more than one item
// is removed from the list during the enumeration.
if (i >= list.Count)
{
if (list.Count == 0)
yield break;
i = list.Count - 1;
}
yield return list[i];
}
}
The example below uses the enumerator to remove all even integers from an ArrayList
.
下面的示例使用枚举器从ArrayList
.
ArrayList list = new ArrayList() {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
foreach (int item in list.GetRemoveSafeEnumerator())
{
if (item % 2 == 0)
list.Remove(item);
}
回答by Brian Wells
I agree with several of the points I've read in this post and I've incorporated them into my solution to solve the exact same issue as the original posting.
我同意我在这篇文章中读到的一些观点,并且我已将它们合并到我的解决方案中,以解决与原始帖子完全相同的问题。
That said, the comments I appreciated are:
也就是说,我赞赏的评论是:
"unless you are using .NET 1.0 or 1.1, use
List<T>
instead ofArrayList
. ""Also, add the item(s) to be deleted to a new list. Then go through and delete those items." .. in my case I just created a new List and the populated it with the valid data values.
“除非你正在使用.NET 1.0或1.1,使用
List<T>
替代ArrayList
。”“另外,将要删除的项目添加到新列表中。然后通过并删除这些项目。” .. 就我而言,我刚刚创建了一个新列表,并用有效数据值填充了它。
e.g.
例如
private List<string> managedLocationIDList = new List<string>();
string managedLocationIDs = ";1321;1235;;" // user input, should be semicolon seperated list of values
managedLocationIDList.AddRange(managedLocationIDs.Split(new char[] { ';' }));
List<string> checkLocationIDs = new List<string>();
// Remove any duplicate ID's and cleanup the string holding the list if ID's
Functions helper = new Functions();
checkLocationIDs = helper.ParseList(managedLocationIDList);
...
public List<string> ParseList(List<string> checkList)
{
List<string> verifiedList = new List<string>();
foreach (string listItem in checkList)
if (!verifiedList.Contains(listItem.Trim()) && listItem != string.Empty)
verifiedList.Add(listItem.Trim());
verifiedList.Sort();
return verifiedList;
}
回答by KevinDeus
Am I missing something? Somebody correct me if I'm wrong.
我错过了什么吗?如果我错了,有人纠正我。
list.RemoveAll(s => s.Name == "Fred");
回答by Nikson Kanti Paul
using ArrayList
also you can try like this
使用ArrayList
你也可以尝试这样
ArrayList arraylist = ... // myobject data list
ArrayList temp = (ArrayList)arraylist.Clone();
foreach (var item in temp)
{
if (...)
arraylist.Remove(item);
}