| |
|
Dynamic foreach, forget about it, use a recursive function
|
| |
| The other day I discovered the power of a recursive
function / method (I.e. recursion) while I was struggling to write some code. I
think one of the focal points of writing good code is writing it in a way that
it expands and contracts dynamically. As well, writing code that you will
rarely, if ever, need to modify again. |
| |
| I was writing a program that would create a Tree View
containing a heiarchy of my family tree. For example |
| |
 |
| |
| I am sure you get the point. It can go forward and
backwards (n) number of times. Initially I began writing nested foreach
statements. However, it quickly became apparent that I would feasibly go on
forever nesting these foreach statements like this: |
| |
foreach (Parent child
in Parent.Children)
{
if(child.children.count > 0)
{
foreach
(Parent grandchild in child.Children)
{
if(child.children.count > 0)
{
foreach (Parent greatgrandchild
in grandchild.Children)
{
if(child.children.count > 0)
{
....FOREVER....etc...
}
else
{
list.Add(grandchild.name);
}
}
}
else
{
list.Add(grandchild.name);
}
}
}
else
{
list.Add(child.name);
}
} |
| |
| The above approach simply would not work. In many design
or code review meetings there would be a discussion about 'How many levels do we
really need'. But in the end, if you implement this approach at some point in
the future you will, very likely, reach the limit. This will result in a source
code modification. This is something we want to avoid. |
| |
| Below is an example of how to write a recursive function /
method (recursion) that will provide the functionality we failed to get in the
above nested foreach approach. It will expand and contract dynamically (n)
times.
|
| |
public static
List<TreeView>
GetFamilyTree(Type ParentType)
{
List<TreeVIew> FamilyTree =
new List<TreeVIew>();
Treeview treeview = new Treeview(ParentType);
PopulateTreeview(ParentType, treeview);
return FamilyTree;
} |
| |
using System.Reflection;
private static
void PopulateTreeview(Type ParentType, TreeviewClass node,
int
depth = 0)
{
if (depth > 1000)
throw new
StackOverflowException("PopulateTreeview depth > 1000");
foreach(PropertyInfo property in ParentType.GetProperties())
{
string name = property.Name;
TreeviewClass treeview =
new
TreeviewClass(name);
node.Children.Add(treeview);
PopulateTreeview(property.PropertyType, treeview, depth + 1);
}
} |
| |
| The List<TreeView> is a class that I store
the name and the children of a relative: |
| |
public
class TreeView
{
public string Name {
get; private set; }
public List<TreeView> Children {
get; private set; }
} |
| |
| You can see in the PopulateTreeview method, I
call the method itself, I.e. recusively. Becuase I am passing the treeview
variable, I created in the GetFamilyTree method, the same treeview
variable is updated (n) times. Awesome!!!
|
| |
| |
|
|
| |
|
|
| |
|
|
| |
| |
| Posts: 113 |
| Comments:
86 |
| Fundamentals:
16 |
| |
 |
| |
| |
|
| |
 |
| |
 |
| |
 |
| |
|
| 2011 December (2) |
| 2011 November (6) |
| 2011 October (7) |
| 2011 September (7) |
| 2011 August (9) |
| 2011 July (9) |
| 2011 June (8) |
| 2011 May (9) |
| 2011 April (7) |
| 2011 March (9) |
| 2011 February (8) |
| 2011 January (8) |
| 2010 December (7) |
| 2010 November (8) |
| 2010 October (4) |
| |
| |
|
| |
|
|
| |
| |
|
The sample code on this website is provided to illustrate a concept and should not be used in
applications or Web sites without proper professional consultation, as it may not illustrate
the safest coding practices. I assume no liability for incidental or consequential damages
should the sample code be used for purposes other than as intended.
|
| |
|
| | | |