Recursively Get Properties & Child Properties Of A Class

c#, recursion, reflection

Solution

You have two problems with your code:

- because of condition `if (property.PropertyType.Assembly == objType.Assembly)` you will omit `System.Collections` like `List<>`

- you do not treat differently `propValue` that are collections. Hence it will print `List` properties, not its elements properties.

You can change that for example into:

public void PrintProperties(object obj, int indent)
{    
    if (obj == null) return;
    string indentString = new string(' ', indent);
    Type objType = obj.GetType();
    PropertyInfo[] properties = objType.GetProperties();
    foreach (PropertyInfo property in properties)
    {
        object propValue = property.GetValue(obj, null);
        var elems = propValue as IList;
        if (elems != null)
        {
            foreach (var item in elems)
            {
                PrintProperties(item, indent + 3);
            }
        }
        else
        {
            // This will not cut-off System.Collections because of the first check
            if (property.PropertyType.Assembly == objType.Assembly)
            {
                Console.WriteLine("{0}{1}:", indentString, property.Name);

                PrintProperties(propValue, indent + 2);
            }
            else
            {
                Console.WriteLine("{0}{1}: {2}", indentString, property.Name, propValue);
            }
        }
    }
}

Problem

I was doing something like Recursively Get Properties & Child Properties Of An Object, but I wanted to use reflection recursively to get each properties. And I got the code from Recursively Print the properties. The problem with the code is: it only goes one level down, I wonder how can you automatically get all the properties using reflection? I just made up the following sample Container code: ``` public class Container { public Bottle MyBottle { get; set; } public List<Address> Addresses { get; set; } public Container() { Address a = new Address(); a.AddressLine1 = "1 Main St"; a.AddressLine2 = "2 Main St"; Addresses = new List<Address>(); Addresses.Add(a); MyBottle = new Bottle(); MyBottle.BottleName = "Big bottle"; MyBottle.BottageAge = 2; } } public class Bottle { public string BottleName { get; set; } public int BottageAge { get; set; } } public class Address { public string AddressLine1 { get; set; } public string AddressLine2 { get; set; } public List<SpecialFolder> SpecialFolders { get; set; } public Address() { SpecialFolders = new List<SpecialFolder>(); SpecialFolder sf = new SpecialFolder(); sf.TemplateFolder = Environment.SpecialFolder.Templates.ToString(); sf.UserFolder = Environment.SpecialFolder.UserProfile.ToString(); SpecialFolders.Add(sf); } } public class SpecialFolder { public string TemplateFolder { get; set; } public string UserFolder { get; set; } } ``` In the Main method: ``` static void Main(string[] args) { Container c = new Container(); PrintProperties(c); } public static void PrintProperties(object obj) { PrintProperties(obj, 0); } public static void PrintProperties(object obj, int indent) { if (obj == null) return; string indentString = new string(' ', indent); Type objType = obj.GetType(); PropertyInfo[] properties = objType.GetProperties(); foreach (PropertyInfo property in properties) { object propValue = property.GetValue(obj, null); if (property.PropertyType.Assembly == objType.Assembly) { Console.WriteLine("{0}{1}:", indentString, property.Name); PrintProperties(propValue, indent + 2); } else { Console.WriteLine("{0}{1}: {2}", indentString, property.Name, propValue); } } } ``` I am hoping to get: ``` MyBottle: BottleName: Big bottle BottageAge: 2 Addresses: AddressLine1: 1 Main St AddressLine2: 2 Main St SpecialFolders: TemplateFolder: Templates UserFolder: UserProfile ``` The result I get now: ``` MyBottle: BottleName: Big bottle BottageAge: 2 Addresses: System.Collections.Generic.List`1[TreeViewReflectionExample.Address] ``` Can someone help me with the PrintProperties method? Thank you very much.

Original source

Related problems