I find myself regularly writing recursive IEnumerable<T>
iterators to implement the same "Descendants" pattern as provided by, for example, XContainer.Descendants
. The pattern I keep implementing is as follows, given a type Foo
with a single-level iterator called 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;
}
}
}
This old StackOverflow question suggests the same pattern. But for some reason it feels weird to me to have to reference three levels of heirarchy (root
, child
, and subchild
). Can this fundamental depth-first recursion pattern be further reduced? Or is this an algorithmic primitive of sorts?
The best I can come up with is to abstract the pattern to a generic extension. This doesn't reduce the logic of the iterator pattern presented above, but it does remove the requirement of defining a Descendants
method for multiple specific classes. On the downside, this adds an extension method to Object
itself, which is a little smelly:
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 */ }