Как использовать LINQ для выбрать всех потомков составного объекта

Как мне сделать ComponentTraversal.GetDescendants () лучше с помощью LINQ?

Вопрос

public static class ComponentTraversal
{
    public static IEnumerable GetDescendants(this Composite composite)
    {
        //How can I do this better using LINQ?
        IList descendants = new Component[]{};
        foreach(var child in composite.Children)
        {
            descendants.Add(child);
            if(child is Composite)
            {
                descendants.AddRange((child as Composite).GetDescendants());
            }
        }
        return descendants;
    }
}
public class Component
{
    public string Name { get; set; }
}
public class Composite: Component
{
    public IEnumerable Children { get; set; }
}
public class Leaf: Component
{
    public object Value { get; set; }
}

Ответ

Я редактировал Крис ответ, чтобы предоставить общий метод расширения, который я добавил в свою общую библиотеку. Я вижу, что это полезно и для других, так что вот оно:

    public static IEnumerable GetDescendants(this T component, Func isComposite, Func> getCompositeChildren)
    {
        var children = getCompositeChildren(component);
        return children
            .Where(isComposite)
            .SelectMany(x => x.GetDescendants(isComposite, getCompositeChildren))
            .Concat(children);
    }

Спасибо, Крис!

Также,

Пожалуйста, посмотрите на Ответ Люка на http://blogs.msdn.com/b/wesdyer/archive/2007/03/23/all-about-iterators.aspx . Его ответ предлагает лучший способ решения этой проблемы в в общем, но я не выбрал его, потому что он не был прямым ответом на мой вопрос.

5
задан smartcaveman 10 March 2011 в 17:05
поделиться