C# 删除第n级嵌套集合中的项

C# 删除第n级嵌套集合中的项,c#,recursion,C#,Recursion,尝试删除树结构对象中的项时遇到问题 我的目标如下 TreeNode { string name; ObservableCollection<TreeNode> Children; } 是否有其他方法可以打破递归。只要不更改原始集合,就可以安全地迭代子节点集合并删除它们。这可以通过创建一个集合数组并对其进行迭代来实现 DeleteNode(ObservableCollection<TreeNode> children, TreeNode nodetodel

尝试删除树结构对象中的项时遇到问题

我的目标如下

TreeNode
{
    string name;
    ObservableCollection<TreeNode> Children;
}

是否有其他方法可以打破递归。

只要不更改原始集合,就可以安全地迭代子节点集合并删除它们。这可以通过创建一个集合数组并对其进行迭代来实现

DeleteNode(ObservableCollection<TreeNode> children, TreeNode nodetodelete)
{
    if (children.remove(nodetodelete))
    {
        return;
    }
    else
    {
        foreach (var child in children.ToArray())
        {
            // If anything is deleted in the collection, it will not break the iteration here, as we are iterating over an Array and not "children"
            DeleteNode(child, nodetodelete);
        }
    }
}
DeleteNode(ObservableCollection子节点,TreeNodeToDelete)
{
if(子项删除(nodetodelete))
{
回来
}
其他的
{
foreach(children.ToArray()中的var child)
{
//如果在集合中删除了任何内容,它将不会中断此处的迭代,因为我们正在迭代数组而不是“子对象”
DeleteNode(子节点,nodetodelete);
}
}
}

这将创建一个新集合供您迭代。如果从
子节点
中删除子节点,则foreach循环不会引发异常。这是因为原始集合已更改,而我们正在迭代次集合。

只要不更改原始集合,就可以安全地迭代子节点集合并删除它们。这可以通过创建一个集合数组并对其进行迭代来实现

DeleteNode(ObservableCollection<TreeNode> children, TreeNode nodetodelete)
{
    if (children.remove(nodetodelete))
    {
        return;
    }
    else
    {
        foreach (var child in children.ToArray())
        {
            // If anything is deleted in the collection, it will not break the iteration here, as we are iterating over an Array and not "children"
            DeleteNode(child, nodetodelete);
        }
    }
}
DeleteNode(ObservableCollection子节点,TreeNodeToDelete)
{
if(子项删除(nodetodelete))
{
回来
}
其他的
{
foreach(children.ToArray()中的var child)
{
//如果在集合中删除了任何内容,它将不会中断此处的迭代,因为我们正在迭代数组而不是“子对象”
DeleteNode(子节点,nodetodelete);
}
}
}

这将创建一个新集合供您迭代。如果从
子节点
中删除子节点,则foreach循环不会引发异常。这是因为当我们在二级集合上迭代时,原始集合被更改了。

我将通过对我的设计做一点小的更改来处理这个问题(假设您问题中的代码片段是类的伪代码):

TreeNode
{
字符串名;
树状体亲本;
可观察收集儿童;
公共作废删除()
{
父。子。移除(此);
}
}
这使得您在操作对象图时维护额外的引用需要做更多的工作,但在执行删除之类的操作时可以节省大量的精力和代码,如上面所示


您还没有展示如何构造
TreeNode
s,但我会创建构造函数的父参数和子参数的集合。

我会通过对我的设计进行一个小的更改来处理这个问题(假设您问题中的片段是类的伪代码):

TreeNode
{
字符串名;
树状体亲本;
可观察收集儿童;
公共作废删除()
{
父。子。移除(此);
}
}
这使得您在操作对象图时维护额外的引用需要做更多的工作,但在执行删除之类的操作时可以节省大量的精力和代码,如上面所示


您还没有展示如何构建
TreeNode
s,但是我会为构造函数的子参数创建父参数和集合。

你事先知道节点在树中只出现一次吗?@Andrew如果你说的是重复的话,可能会有重复的,因为在某个级别上,我有一个占位符节点来分组项目。你能发布你实际的、准确的代码吗?你在这里发布的内容甚至不会编译。我想我看到有人发布了答案,但它被删除了,因为集合不能在foreach循环中操作。我希望那个人不要删除他的评论,这样我就可以相信他了。可能重复的您是否事先知道节点在树中只出现一次?@Andrew如果您说的是重复,则可能会重复,因为在特定级别,我有一个占位符节点来将项目分组。您可以发布您的实际、准确的代码吗?你在这里发布的内容甚至不会编译。我想我看到有人发布了答案,但它被删除了,因为集合不能在foreach循环中操作。我希望那个人不要删除他的评论,这样我就可以相信他了。一个非常优雅的解决方案的可能复制品!一个非常优雅的解决方案!
DeleteNode(ObservableCollection<TreeNode> children, TreeNode nodetodelete)
{
    if (children.remove(nodetodelete))
    {
        return;
    }
    else
    {
        foreach (var child in children.ToArray())
        {
            // If anything is deleted in the collection, it will not break the iteration here, as we are iterating over an Array and not "children"
            DeleteNode(child, nodetodelete);
        }
    }
}
TreeNode
{
    string name;
    TreeNode Parent;
    ObservableCollection<TreeNode> Children;

    public void Delete()
    {
        Parent.Children.Remove(this);
    }
}