views:

323

answers:

3

Say i have these two classes

    public class Container
    {
        public string name { get; set; }
        public Inner Inner { get; set; }
    }

    public class Inner
    {
        public string text { get; set; }
        public Inner2 Innert2 { get; set; }
    }

    public class Inner2 {}

How would i go, given an instance of the Container class find all nested class instances. Only really concerned about the classes not the strings etc.

Needs to be generic so that if Inner had a class it would still work. Also if there is a List or Ienumerable of a class it needs to find them too.

Cheers.

A: 

You want to recurively loop through the object graph with Reflection

http://msdn.microsoft.com/en-us/library/ms173183(VS.80).aspx

Chad Grant
I am not sure his question is related to object graph. He is talking about nested classes and not about objects composition.
+2  A: 

Using Reflection would be the way to go. Here's a simple snippet of code that would allow you do get the properties of a class and, if the property is not of a value type, recursively call itself. Obviously if you want specific behavior with Enums or IEnumerable members, you'll need to add that.

public void FindClasses(object o)
{
    if (o != null)
    {
        Type t = o.GetType();
        foreach(PropertyInfo pi in t.GetProperties())
        {
            if(!pi.PropertyType.IsValueType)
            {
                // property is of a type that is not a value type (like int, double, etc).
                FindClasses(pi.GetValue(o, null));
            }
        }
    }
}
CMerat
A: 

Your question would work if the code in your example was as such:

public class Container
{
    public string name { get; set; }
    public Inner Inner { get; set; }
}

public class Inner
{
    public string text { get; set; }
    public List<Inner> MoreInners { get; set; }
}

In this case, you could either use an external iterator class to do the work, or build the recursion directly into the Container class. I will do the latter:

public class Container
{
    public string name { get; set; }
    public Inner Inner { get; set; }

    public List<Inner> SelectAllInner()
    {
        List<Inner> list = new List<Inner>();
        SelectAllInner(Inner, list);
        return list;
    }

    private void SelectAllInner(Inner inner, List<Inner> list)
    {
        list.Add(inner);
        foreach(Inner inner in MoreInners)
            SelectAllInner(inner, list);
    }
}

public class Inner
{
    public string text { get; set; }
    public List<Inner> MoreInners { get; set; }
}
Nathan Ridley