我发现自己经常编写递归IEnumerable<T>
迭代器来实现相同的“后代”模式,例如,XContainer.Descendants
. 我继续实现的模式如下,给定一个Foo
具有单级迭代器的类型,称为Children
:
public static IEnumerable<Foo> Descendants(this Foo root) {
foreach (var child in root.Children()) {
yield return child;
foreach (var subchild in child.Descendants()) {
yield return subchild;
}
}
}
这个旧的 StackOverflow 问题提出了相同的模式。但是由于某种原因,我觉得必须引用三个层次结构(、、和)感到root
很child
奇怪subchild
。这种基本的深度优先递归模式可以进一步减少吗?或者这是一种算法原语?
我能想到的最好的办法是将模式抽象为通用扩展。这不会减少上面介绍的迭代器模式的逻辑,但它确实消除了Descendants
为多个特定类定义方法的要求。不利的一面是,这给自己增加了一个扩展方法Object
,有点臭:
public static IEnumerable<T> SelectRecurse<T>(
this T root, Func<T, IEnumerable<T>> enumerator) {
foreach (T item in enumerator(root))
{
yield return item;
foreach (T subitem in item.SelectRecurse(enumerator))
{
yield return subitem;
}
}
}
// Now we can just write:
foreach(var item in foo.SelectRecurse(f => f.Children())) { /* do stuff */ }