Skip to main content
 首页 » 编程设计

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

2024年02月03日26lexus

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

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

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) 中处理它。