通过反射在C#中获取嵌套属性值

4

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; }
}

主要功能:

        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));
                }
            }
        }

我想获取叶节点的属性名称和值。我可以获取名称,但是当我尝试获取值(分别为1、2、3、4)时,出现以下错误:
“对象不符合目标类型。”
我一直在努力解决这个问题。有人能帮我吗?

你正在将父对象实例传递给叶子属性信息获取器。 - vgru
为什么需要反射? - johnny 5
2个回答

4

当将一个对象实例传递给 GetValue 方法时,需要传递正确类型的实例:

// 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));
        }
    }
}

你可以递归地完成这个操作,以简化(通用化)整个过程:
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);

谢谢。运行得很顺利 :) - Beelal Ahmed
@Beelal:另外,如果您不想将树深度硬编码,我建议使用类似下面递归方法的东西。 - vgru
我会看一下它。 - Beelal Ahmed
请告诉我如何在Windows通用应用程序中实现,因为它没有GetProperties()方法。 - Beelal Ahmed

0

问题出在这个表达式:

leafProperty.GetValue(obj, null)

您正在传递根对象以获取叶子属性。在处理每个属性时,您需要获取其值,然后调用 GetValue


请问你能指导我一下吗,如何使用反射API?我对此还不熟悉。 - Beelal Ahmed
@BeelalAhmed - 看一下Groo的答案。 - Sean

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接