【问题标题】:Iterator for hierarchical class分层类的迭代器
【发布时间】:2019-04-21 05:28:51
【问题描述】:

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

【问题讨论】:

  • 您是否考虑过使用不同的类型来表示汽车和动物?它们可以从代表树结构的通用抽象基类继承。
  • 有了给定的详细程度,一个简单的enum NodeType { Animal, Car } 将与继承一样好。即使你想要AnimalCar

标签: c# tree iterator hierarchy ienumerator


【解决方案1】:

将此方法添加到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;

见:

【讨论】:

  • 我决定不设置 Children = new List( ) 因为它会增加 RAM 使用率。层次结构中大约有 200 万个笔记。
  • 另外一件奇怪的事情:如果不使用 (),我无法访问枚举器 myTopNode.DescendantsAndSelf()。有没有办法定义这个所以不需要()?有没有必要进行让步;这里?没有它似乎也能正常工作。
  • 这是一种方法。因此 () 是必需的。您可以改为将其设为 getter-only 属性:public IEnumerable&lt;Node&gt; DescendantsAndSelf { get { yield return this; ... } }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-20
相关资源
最近更新 更多