我正在尝试遍历项目集合,执行操作,然后删除当前索引处的项目。
我目前的实现方式是这样的:
foreach (CormantRadPane pane in GetPanes().ToList())
{
pane.Clear();
StateManager.Remove(pane);
LayoutManager.Instance.RegisteredPanes.Remove(pane);
Items.Remove(pane);
}
通过调用 ToList,我创建了集合的副本,但保留了对第一个集合中每个对象的引用。这使我可以迭代从 GetPanes 返回的集合,而无需“技术上”修改集合。
这显然容易出现一些严重难以追踪的错误。以干净的方式执行此类逻辑的标准方法是什么,但也更清楚正在发生的事情的复杂性?
我环顾四周,看到了诸如使用 for 循环和向后遍历列表之类的东西,但这看起来真的很笨重。我的感受与保留“要删除”的第二个项目列表,然后在第一个循环完成后遍历该列表,删除第二个列表中找到的每个对象的感觉大致相同。
你是怎么处理的?谢谢。
最佳答案
您可以创建一个变量并使用它,而不是当前的方法,我建议使用 for
循环来删除 Pane ,技巧就是反向迭代它:
var panes = GetPanes();
int count = panes.Count;
for(int i= count - 1; i>=0; i--)
{
pane = panes[i];
pane.Clear();
StateManager.Remove(pane);
LayoutManager.Instance.RegisteredPanes.Remove(pane);
//Items.Remove(pane);
Items.RemoveAt(i);
}
调用 Items.Remove(pane);
需要 O(n)(如果是列表)但是在使用 Items.RemoveAt(i);
的情况下需要O(1),因此您当前的方法采用 O(n^2),但如果您可以调用 RemoveAt(index)(您有一些列表并且它们以相同的方式排序),您可以在 O(n) 中处理它。
关于c# - 迭代和修改集合的最佳实践?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7972601/