How to use LINQ to select all descendants of a composite object

后端 未结 4 1769
终归单人心
终归单人心 2020-12-16 06:34

How can I make ComponentTraversal.GetDescendants() better using LINQ?

Question

public static class ComponentTraversal
{
    public sta         


        
4条回答
  •  执念已碎
    2020-12-16 07:12

    There are often good reasons to avoid (1) recursive method calls, (2) nested iterators, and (3) lots of throwaway allocations. This method avoids all of those potential pitfalls:

    public static IEnumerable GetDescendants(this Composite composite)
    {
        var stack = new Stack();
        do
        {
            if (composite != null)
            {
                // this will currently yield the children in reverse order
                // use "composite.Children.Reverse()" to maintain original order
                foreach (var child in composite.Children)
                {
                    stack.Push(child);
                }
            }
    
            if (stack.Count == 0)
                break;
    
            Component component = stack.Pop();
            yield return component;
    
            composite = component as Composite;
        } while (true);
    }
    

    And here's the generic equivalent:

    public static IEnumerable GetDescendants(this T component,
        Func hasChildren, Func> getChildren)
    {
        var stack = new Stack();
        do
        {
            if (hasChildren(component))
            {
                // this will currently yield the children in reverse order
                // use "composite.Children.Reverse()" to maintain original order
                // or let the "getChildren" delegate handle the ordering
                foreach (var child in getChildren(component))
                {
                    stack.Push(child);
                }
            }
    
            if (stack.Count == 0)
                break;
    
            component = stack.Pop();
            yield return component;
        } while (true);
    }
    

提交回复
热议问题