C# - 集合已修改;枚举操作可能无法执行
Posted
技术标签:
【中文标题】C# - 集合已修改;枚举操作可能无法执行【英文标题】:C# - Collection was modified; enumeration operation may not execute [duplicate] 【发布时间】:2015-06-17 16:26:33 【问题描述】:在我编写的冗长代码中有一个按钮单击事件。我有一个对象列表。每次单击按钮时,都应修改列表(例如,应删除某些项目),然后使用 foreach 循环进行迭代。
List<Person> lp=new List<Person>();
lp.RemoveAt(2);
foreach(Person j in lp)
// do something
当我尝试执行上述代码时,它会导致异常。
InvalidOperationException : 集合被修改;枚举操作可能无法执行。
我在互联网上找到了一些解决方案并尝试了它们。其中之一是,
foreach(Person j in lp.ToList())
// do something
但没有什么可以阻止异常。
有人可以帮忙吗?
【问题讨论】:
List 是否有可能被其他线程访问? 向我们展示循环内的代码 【参考方案1】:显然,您的 do something
代码正在尝试修改集合。
在迭代集合时修改集合通常是个坏主意。
你可以做什么:
将集合复制到另一个。
foreach(Person j in lp.ToArray())
或
foreach(Person j in new List<Person>(lp))
使用修改项目的临时集合。
List<Person> itemsToDoSomething = new List<Person>();
foreach(Person j in lp)
itemsToDoSomething.Add(j);
然后应用所需的操作。例如,从集合中删除项目:
lp.RemoveAll(item => itemsToDoSomething.Contains(item));
【讨论】:
谢谢!这帮助我解决了它! 不是循环键是个好主意吗? ***.com/a/26864676/1589885 new ListList<T>
类的新实例,该实例包含从指定集合复制的元素,并且有足够的容量容纳复制的元素数量。”是的,请举个例子。
@Dmitry 是的,它是一个副本。但是复制过程本身不是线程安全的。问题出在运行 ToArray 时。 ToArray 没有解决问题,只是将其迁移到另一个问题:Destination array was not long enough. Check destIndex and length
但不太可能发生,因为 ToArray() 在内部没有任何处理的情况下速度更快。和构造函数版本是一样的实现,通过调用CopyTo
这里的例子:dotnetfiddle.net/IqVbZ8【参考方案2】:
尝试修改克隆列表并将引用复制回来(只是一个想法):
List<Person> newList = new List<Person>(lp);lp = newList;
基本上不允许在迭代列表时修改列表
【讨论】:
谢谢!但还是一样 dosomething 确实做了一些修改你正在迭代的列表的事情。 我的意思是遍历您的 lp,但修改 newList(这似乎是您的要求),然后将您的 newList(已修改)分配回您的原始列表(即 lp)以上是关于C# - 集合已修改;枚举操作可能无法执行的主要内容,如果未能解决你的问题,请参考以下文章