After writing my last post I spent some time thinking about certain places where the DeepEnumerator class helped me, and one of the uses that I came across was based on a particular challenge. I had a class that represented the tree structure that I talked about in my last post, namely it adhered to the following principle:
What I discovered is that it’s fairly common to have a situation where the parent defines it’s children in the aforementioned manner, but often in such cases, the children do not define their parents. What I wanted to do is to handle this case by creating a new class that holds the parent and the child and do it in a generic way.
For the purpose of illustrating anonymous types let’s do it first with anonymous types. Note: The following example uses LINQ for terseness and expressiveness, but it’s not required.
First, given the aforementioned class T, let’s define the anonymous type, given an instance of T called parent.
This code may look odd but all we really are doing here is defining the concept of a root, and a root is an item that has no parent. We use default(T) to define the type. To enumerate, we know we want to enumerate starting with root, which internally represents a tuple of a parent and child, but the challenge is mapping root to IEnumerable<AnonymousType> where anonymous type is the type of root that we just defined.
To do so let’s use linq:
All this does is it takes the elementAndParent and maps it to a query that takes all the children under elementAndParent.Element(which is really the element that we are using currently on the tree) and returns a new anonymous type with that child as Element, and the current element as Parent.
Let’s look at it in the full context. Note I’ve defined our cute dog Kadi here as a person. Call it artistic license:
Note I filtered out entries that don’t have parents, as those are roots and I don’t really care about them.
The only drawback to this approach is that anonymous types have to be local in scope, which prevents me from reusing this code (obviously not ideal). To fix this let’s declare the anonymous type as a real type:
Once we have this helper class we can define a function like so:
What if we wanted to be able to walk all the way up the parents from the current node. Pretty easy actually. We just make a couple modifications. First let us define a class:
This class basically makes parent the same type as the type itself, allowing us to get the parent’s parent. We can then modify the enumeration like so:
To test, let’s make a new method:
If you run the method you’ll see that each element can now walk up it’s hierarchy to get it’s ancestry.
These methods could be extended to support all the options that the deep enumerator does, but I’ve not done so in the interest of brevity. Note I also could have used the Tuple class for this, but I chose to create my own for clarity.