patterncsharpMinor
Extension method to enumerate a hierarchical object
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:
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:
And here is the domain object:
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.
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.