分层 class 的迭代器
Iterator for hierarchical class
我有一个 C# class 来定义层次结构(比下面的示例复杂得多)。 class 有一个 Parent
并且可能 Children
是同一个 class。
我正在尝试为顶级对象编写一个迭代器,它将允许我访问 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)
将此方法添加到 Node
class:
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 的建议并从抽象基础 class 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;
参见:
我有一个 C# class 来定义层次结构(比下面的示例复杂得多)。 class 有一个 Parent
并且可能 Children
是同一个 class。
我正在尝试为顶级对象编写一个迭代器,它将允许我访问 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)
将此方法添加到 Node
class:
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 的建议并从抽象基础 class 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;
参见: