Search code examples
c#reflectioninner-classes

How to use reflection on nested classes in order to get values


I have to an upper class with nested classes

public class Preferences
{
    public FunctionClass function { get; set; } = new FunctionClass();
    public class FunctionClass
    {
        public string programfolder { get; set; } = "";
        ...
    }

    public LoggerClass logger { get; set; } = new LoggerClass();
    public class LoggerClass 
    {
        public string logFolder { get; set; } = "Log";
        ...
    }

    public OptionClass options { get; set; } = new OptionClass();
    public class OptionClass
    {
        public bool showGraphics { get; set; } = true;
        ...
    }

    public MqttSpSetupClass MqttSpSetup { get; set; } = new MqttSpSetupClass();
    public class MqttSpSetupClass
    {
        public string strAddress { get; set; } = "localhost";
        ...
    }
}

so I want reflection to cycle on all member of each inner class

PropertyInfo[] props_Outer = typeof(IoAppPreferences).GetProperties();
int counter = 0;
foreach (PropertyInfo prop_Upper in props_Outer)
{
    var sName_Outer = prop_Upper.Name;
    var val_Outer = props_Outer.GetValue(counter ++);
        
    PropertyInfo[] properties_Inner;
    switch (sName_Outer.ToUpper())
    {
        case "DIMS": properties_Inner = typeof(IoAppPreferences.DimsClass).GetProperties(); break;
     ...    
    }

             
    foreach (PropertyInfo prop_Inner in properties_Inner)
    {
        var sName = prop_Inner.Name;
        //prefs.function

        var sVal = prop_Inner.GetValue(val_Outer);<------ERROR

        switch (prop_Inner.Name.ToUpper())
        {
         ...            
        }
    }

I get an error where I put the arrow. And the reason is that val_Outer is FunctionClass function while if I hardcode prefs.function it is ok. Of course, I can put a switch per each one, but my question is: is there a better way to solve it?

I have seen this solution but can't fit to my needs


Solution

  • You got error because val_Outer is wrong instance. You are trying to get value out of counter integer props_Outer.GetValue(counter ++)

    If your goal is to get property values from nested classes you must have instance of Preferences object:

        var appPreferences = new Preferences();
        var propsOuter = appPreferences.GetType().GetProperties();
    
        foreach (var po in propsOuter)
        {
            var valueOuter = po.GetValue(appPreferences);
            Console.WriteLine($"{po.Name}");
    
            if (valueOuter == null) continue;
    
            var propsInner = valueOuter.GetType().GetProperties();
            foreach (var pi in propsInner)
            {
                var valueInner = pi.GetValue(valueOuter);
                Console.WriteLine($"{pi.Name}: {valueInner}");
            }
        }
    

    But getting values through reflection is pretty much useless if you already have object instance.