分层类的迭代器

时间:2018-11-18 19:37:41

标签: c# tree iterator hierarchy ienumerator

我有一个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)

1 个答案:

答案 0 :(得分: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永远不会为空,并且HasChildren将实现为:

public bool HasChildren => Children.Count > 0;

请参阅: