简体   繁体   中英

Get nested property values through reflection C#

I have following code.

Classes:

public class AlloyDock
{
    public int Left { get; set; }
    public int Right { get; set; }
}

public class Charger
{
    public int Left { get; set; }
    public int Right { get; set; }
}
public class VehicleControlTest
{
    public Charger Charger1 { get; set; }
}
public class BasicControlTest
{
    public AlloyDock AlloyDock1 { get; set; }
}
class Appointment
{
    public BasicControlTest BasicControlTest1 { get; set; }
    public VehicleControlTest VehicleControlTest1 { get; set; }
}

Main Function:

        var obj = new Appointment();
        obj.BasicControlTest1 = new BasicControlTest();
        obj.BasicControlTest1.AlloyDock1 = new AlloyDock();
        obj.BasicControlTest1.AlloyDock1.Left = 1;
        obj.BasicControlTest1.AlloyDock1.Right = 2;

        obj.VehicleControlTest1 = new VehicleControlTest();
        obj.VehicleControlTest1.Charger1 = new Charger();
        obj.VehicleControlTest1.Charger1.Left = 3;
        obj.VehicleControlTest1.Charger1.Right = 4;


        var parentProperties = obj.GetType().GetProperties();
        foreach (var prop in parentProperties)
        {
            // Get Main objects inside each test type.
            var mainObjectsProperties = prop.PropertyType.GetProperties();
            foreach (var property in mainObjectsProperties)
            {
                var leafProperties = property.PropertyType.GetProperties();
                foreach (var leafProperty in leafProperties)
                {
                    Console.WriteLine("{0}={1}", leafProperty.Name, leafProperty.GetValue(obj, null));
                }
            }
        }

I want to get property name and value of leaf node. I am able to get name but when I try to get value (1,2,3,4 respectively). I am getting below error.

Object does not match target type.

I am just banging my head to solve this problem. Can anybody help me with that.

When passing an object instance to the GetValue method, you need to pass the instance of the correct type:

// 1st level properties
var parentProperties = obj.GetType().GetProperties();
foreach (var prop in parentProperties)
{
    // get the actual instance of this property
    var propertyInstance = prop.GetValue(obj, null);

    // get 2nd level properties
    var mainObjectsProperties = prop.PropertyType.GetProperties();

    foreach (var property in mainObjectsProperties)
    {
        // get the actual instance of this 2nd level property
        var leafInstance = property.GetValue(propertyInstance, null);

        // 3rd level props
        var leafProperties = property.PropertyType.GetProperties();

        foreach (var leafProperty in leafProperties)
        {
            Console.WriteLine("{0}={1}",
                leafProperty.Name, leafProperty.GetValue(leafInstance, null));
        }
    }
}

You might do this recursively to simplify (generalize) the whole thing:

static void DumpObjectTree(object propValue, int level = 0)
{
    if (propValue == null)
        return;

    var childProps = propValue.GetType().GetProperties();
    foreach (var prop in childProps)
    {
        var name = prop.Name;
        var value = prop.GetValue(propValue, null);

        // add some left padding to make it look like a tree
        Console.WriteLine("".PadLeft(level * 4, ' ') + "{0}={1}", name, value);

        // call again for the child property
        DumpObjectTree(value, level + 1);
    }
}

// usage: DumpObjectTree(obj);

The problem is with this expression:

leafProperty.GetValue(obj, null)

You are passing the root object in to get the leaf property. As you process each property you need to get its value and then call GetValue against it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM