用于分层类的迭代器

问题描述 投票:2回答:1

我有一个C#类来定义层次结构(比下面的例子复杂得多)。该班有一个Parent,可能是同一类的Children

我正在尝试为顶级对象编写一个迭代器,这将允许我访问foreach循环中的所有内容。

class Node
{
    public Node Parent { get; private set; }
    public bool HasParent { get { return (Parent != null); } }
    public string Name { get; private set; }
    public bool IsAnimal { get; set; }
    public bool IsCar { get; set; }
    public List<Node> Children { get; private set; }
    public bool HasChildren { get { return (Children != null); } }

}

想要像这样访问:

foreach (Node myNode in TopNode.Contents)

有多个迭代器来遍历不同类型的Children会很好:

foreach (Node myNode in TopNode.Animals)

要么

foreach (Node myNode in TopNode.Cars)
c# tree iterator hierarchy ienumerator
1个回答
2
投票

将此方法添加到Node类:

public IEnumerable<Node> DescendantsAndSelf()
{
    yield return this;
    if (Children != null) {
        foreach (Node child in Children) {
            foreach (Node node in child.DescendantsAndSelf()) {
                yield return node;
            }
        }
    }
}

并且您不需要针对不同类型的节点使用不同的迭代器。只需使用.Where(...)

var allAnimals = myTopNode.DescendantsAndSelf()
    .Where(n => n.IsAnimal);

如果您了解@LasseVågsætherKarlsen的建议并从抽象基类Node派生出不同的节点类型,那么您可以像Animal一样输入动物:

IEnumerable<Animal> allAnimals = myTopNode.DescendantsAndSelf()
    .OfType<Animal>();

您也可以将Children声明为:

public List<Node> Children { get; } = new List<Node>();

像这样,Children永远不会为null,而HasChildren将被实现为:

public bool HasChildren => Children.Count > 0;

看到:

© www.soinside.com 2019 - 2024. All rights reserved.