c# - 迭代和修改集合的最佳实践?

标签 c# collections foreach

我正在尝试遍历项目集合,执行操作,然后删除当前索引处的项目。

我目前的实现方式是这样的:

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/

相关文章:

每个 PDF 的 VBA 嵌套

c# - 引用文件的相对路径

c# - 对接口(interface)和实现感到困惑

c# - 在 WPF 中更改按钮图像的更好算法

java - 如果调用了remove()但什么都不做,迭代器会被损坏吗?

java - 需要创建一个类似于 HashSet 的数据结构,但应该具有包含元素的频率

c# - 为什么这段操作PE文件头的代码使用了这么奇怪的偏移值?

java - 任何人都可以向我解释这个 Java 问题吗?

php - 如何测试数组指针是否在foreach循环中的第一个元素

c# - List ForEach 休息