在C#中返回foreach循环中的一次迭代

时间:2014-04-15 14:09:34

标签: c# .net collections foreach iteration

我有一个foreach循环,它在C#中迭代treeView的不同级别,其简化版本如下所示:

foreach (TreeNode childNode in currentNode.Nodes)
{
    if (!someCondition)
    {
        currentNode.Remove();                    
    }
}   

但问题是当一个节点(例如来自node1,node2,node3和node4的列表)被删除时,列表变得更短,foreach循环跳过一次迭代(例如,假设是node2)要删除列表将成为node1,node3和node4,foreach循环认为的下一个节点将是node4而不是node3)。这是因为框架将这些节点存储在数组/列表中,因此我想知道当我想从树中删除节点时是否有可能使foreach循环返回一次迭代。

我是.NET框架中的新手,所以非常感谢您的帮助。

4 个答案:

答案 0 :(得分:4)

通过设置

,可以使用Linq实现所需的结果
currentNode.Nodes = currentNode.Nodes.Where( n => SomeCondition( n ) ).ToList();

或类似的东西,因此不需要显式迭代。一个不太优雅的解决方案是使用向后运行的显式for循环,以便循环索引不会变为无效。但是,如果有更结构化的方法,我会考虑这种不好的做法。

答案 1 :(得分:3)

您可以在此处使用 for loop

// Pay attention to reversed order:
// each currentNode.Remove() changes currentNode.Nodes.Count 
for (int i = currentNode.Nodes.Count - 1; i >= 0; --i)  {
  TreeNode childNode = currentNode.Nodes[i];

  if (!someCondition) {
    currentNode.Remove();                    
  }
}

答案 2 :(得分:1)

不可能这是不可能的,因为严格意义上foreach循环的迭代没有被“索引”。
但是,for循环被编入索引,因为您自己为其提供了计数机制。在那里你可以改变你的柜台。

答案 3 :(得分:0)

通常,修改您在foreach中迭代的集合并不是一个好主意。您应该考虑使用for循环,并手动跟踪当前索引。