HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Extension method to enumerate a hierarchical object

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
methodobjectextensionhierarchicalenumerate

Problem

I have a domain object that I have no control over which itself contains a collection of this same type. This is a classical hierarichal representation like in a tree node hierarchy. I would like to be able to enumerate the whole hierarchy in a single call so I came up with this extension method:

public static class MyObjectExtensions
{
    public static IEnumerable FindAllObjectsRecursive(this MyObject myObject)
    {
        var objects = new List();

        objects.Add(myObject);

        foreach (MyObject innerObject in myObject.Objects)
        {
            objects.AddRange(innerObject.FindAllObjectsRecursive());
        }

        return objects;
    }
}


Unfortunately I am not really satisfied by this method because it would definitely cause issues in a large tree span scenario. So I was wondering if anyone would have a solution for that. I did think of using a parameter for the list but I was thinking there must be a better solution.

Here is how I intend to use this method:

var myObject = new MyObject();
var allObjects = myObject.FindAllObjectsRecursive();


And here is the domain object:

public class MyObject
{
    public IEnumerable Objects { get; set; }
}

Solution

There is a way, and it is beautiful. Instead of using recursion, you use iteration by placing the top level object on a Stack (or Queue depending on whether you want a depth-first or a breadth-first search). Then you go into a loop where you pop off the first item, check to see if it has descendants, and add them to the stack. By the time the stack/queue is empty you'll have traversed the entire tree.

You were halfway there with your decision to manage a collection that represents the entire set of objects, but the nature of the Stack/Queue allows you to access deeper and deeper properties without having to go deeper and deeper in the call stack.

Example from MSDN on how to traverse a directory tree:
http://msdn.microsoft.com/en-us/library/bb513869.aspx

Whether you choose to implement this as an extension method or not is up to you. I also strongly advise asking yourself whether you really need a collection of all descendants, or if you simply want to iterate through all descendants of a certain object? The answer to that question will determine whether the traversal belongs in what would be acting on the top-level object or whether the traversal should be abstracted away.

Context

StackExchange Code Review Q#74082, answer score: 5

Revisions (0)

No revisions yet.