Енумератор слишком рано завершает работу

Суть задачи: обойти дерево (preorder), но у меня не получается вернуть нормальную IEnumerable<VisualElement>, возвращается только первый элемент и на этом цикл заканчивается. Алгоритм правильный, поскольку если метод сделать void и вместо yield return root сделать Console.WriteLine(root), то всё выводится в правильном порядке.

public static IEnumerable<VisualElement> GetChildren(VisualElement root)
{
    yield return root;
    if (root?.Children != null)
        foreach (var child in root.Children)
        {
            GetChildren(child);
        }
}

Конечно, можно добавить поле List<VisualElement>, и вместо yield return сделать добавление в коллекцию, но мне кажется этот способ плохим, поскольку при повторном запуске метода List будет непустым.


Ответы (1 шт):

Автор решения: aepot

Рекурсия же

public static IEnumerable<VisualElement> GetChildren(VisualElement root)
{
    yield return root;
    if (root?.Children != null)
        foreach (var child in root.Children)
        {
            GetChildren(child); // <-- отсюда значения не забираете
        }
}

То есть надо энумератором так же вытаскивать значения из дочерних вызовов

public static IEnumerable<VisualElement> GetChildren(VisualElement root)
{
    yield return root;
    if (root?.Children != null)
        foreach (var child in root.Children)
        {
            foreach (var node in GetChildren(child))
                yield return node;
        }
}

Стоит только обратить внимание, что данная рекурсия хвостовая и можно оптимизировать до цикла, полностью избавившись от рекурсии.

→ Ссылка