是否可以编写递归的IEnumerable <T>

Joa*_*nge 8 .net c# collections recursion ienumerable

我有一个类:

class Spline
    int ChildrenCount;
    Spline GetChild (int index)

class SplineCollection : IEnumerable<Spline>
    Spline Master
Run Code Online (Sandbox Code Playgroud)

是否可以为SplineCollection写一个递归的IEnumerable,它将逐个返回所有的子节点?

编辑:所以Master是根Box,其子级的层次结构可以是任何深度.

编辑:通过使用名称Box,我认为我困惑了一些人.它意味着是一个几何对象,而不是一个容器.所以将它改为Spline.

Bri*_*eon 11

我会手动维护堆栈,而不是依赖于调用堆栈.原因是,如果您通过递归调用获取后代的方法来使用调用堆栈,则IEnumerable<Spline>必须为每个Spline访问者创建一个new .那将是低效的.您可以使用自己的堆栈显着改善遍历.

public IEnumerable<Spline> Descendants
{
    get
    {
        // This performs a simple iterative preorder traversal.
        var stack = new Stack<Spline>(new Spline[] { this });
        while (stack.Count > 0)
        {
            Spline current = stack.Pop();
            yield return current;
            for (int i = current.ChildrenCount - 1; i >= 0; i--)
            {
                stack.Push(current.GetChild(i));
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我希望我可以投票10次.这比*递归解决方案更有效率,只需要几秒钟的思考.实际上,您可以将其概括为`Flatten`函数以简化任何递归迭代器. (3认同)

the*_*oop 9

这将对Box"树" 进行深度优先遍历.然后,您可以在Master框中调用此方法以返回所有递归子项.

public class Box
{
    // ...

    public IEnumerable<Box> GetBoxes() 
    {
        yield return this;

        for (int i=0; i<box.ChildrenCount; i++)
        {
            foreach (Box child in box.GetChild(i).GetBoxes())
            {
                 yield return child;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)