C# &引用;集合已修改…”;问题
我有一个函数,它检查对象列表,查看它们是否被单击,并相应地触发OnClick事件。我相信该功能工作正常,但我有一个问题: 当我钩住一个OnClick事件并移除元素并将其插入列表中的不同位置(此程序的典型功能)时,我得到了“Collection was modified…”错误 我相信我了解正在发生的事情:C# &引用;集合已修改…”;问题,c#,collections,exception,C#,Collections,Exception,我有一个函数,它检查对象列表,查看它们是否被单击,并相应地触发OnClick事件。我相信该功能工作正常,但我有一个问题: 当我钩住一个OnClick事件并移除元素并将其插入列表中的不同位置(此程序的典型功能)时,我得到了“Collection was modified…”错误 我相信我了解正在发生的事情: 必要时,该函数循环遍历每个对象触发OnClick事件 触发一个事件,对象根据钩住的函数更改列表中的位置 在遍历集合时修改集合会引发异常 我的问题是,如何允许函数遍历所有对象,在适当的时间触
- 必要时,该函数循环遍历每个对象触发OnClick事件
- 触发一个事件,对象根据钩住的函数更改列表中的位置
- 在遍历集合时修改集合会引发异常
- 在迭代中使用集合的副本而不是初始集合
- 如果您有一个支持索引(如列表)的集合,则可以使用“for”循环,而不是使用“foreach”进行迭代
- 把清单复印一份。在副本上迭代
- 列出需要进行的更改。完成迭代后应用更改
- 这类问题有两种通用解决方案:
如果要将进行更改的代码与执行循环的代码解耦,“使用索引”选项听起来不合适。如果要使用foreach循环来操作集合,请尝试将其替换为
for (int a = items_count - 1; a >= 0; --a)
您看到的行为是: C语言的foreach语句# 语言(适用于Visual Basic中的每种语言) 隐藏了问题的复杂性 统计员。因此,使用foreach 建议使用,而不是直接使用 操作枚举数 枚举数可用于读取 集合中的数据,但它们 无法用于修改 基础集合 触发同步执行的事件与从
foreach
循环中修改集合具有相同的效果
我的首选是使用进行反向循环,这避免了根据是否插入内容更新循环索引的条件逻辑:
for (var i = collection.Count - 1; i >= 0; i--) {
if (condition)
collection.Insert(i, item);
}
相应的递增循环如下所示:
for (var i = 0; i < collection.Count; i++) {
if (condition) {
collection.Insert(i, item);
i++;
}
}
for(var i=0;i
在迭代集合时,无法修改它们。您需要先标记要从集合中删除的项目,然后再删除它们。根据需要,您可以在删除项目之前或之后触发事件。这个代码片段显示了我所涉及的内容
List itemsTobeRemoved=新列表();
对于(var i=0;i
foreach(itemsTobeRemoved中的变量i=0){
如果(条件){
收集、移除(i);
}只有当您可以直接访问收藏项目的“按索引”时,这才可以。我认为第二个选项听起来最好。我只需在更新过程中记录对列表的任何修改,然后在迭代完成后应用它们。请注意,您必须明确“位置”的确切含义这意味着当你做不止一次编辑时——“交换1和2”和“交换2和3”,或者“在A之后移动C”和“删除A”。我通常发现,通过在副本上迭代来生成做正确事情的代码更容易,尽管这可能效率极低。