0

Suppose I have a Class which consists of other classes which have properties like this:

public class classA {
    public classAA classAA = new classAA();
    public classAB classAB = new classAB();

}

public class classAA {
    public string propertyA { get; set; }        
}

public class classAB {
    public string propertyB { get; set; }
}

And I want to iterate over all classA fields, then iterate over their properties and get their values. I have created simple console application to test this.

classA classA = new classA();
classA.classAA.propertyA = "A";
classA.classAB.propertyB = "B";

    foreach (FieldInfo memberAField in classA.GetType().GetFields()) {
        Console.WriteLine(memberAField.Name + " " + memberAField.MemberType + " " + memberAField.FieldType);
        foreach (PropertyInfo classAProperty in memberAField.FieldType.GetProperties()) {
            Console.WriteLine("name: " + classAProperty.Name);
            Console.WriteLine(" to value: " + classAProperty.GetValue(memberAField));
            }
        }

Now I don't know what to pass to GetValue function. I have tried everything I could think of, but I always get error "Object does not match target type." I think the problem is that memberAField is FieldInfo object, but how can I get the actual System object?

EDIT: Thank you both for answers! Also, I do not think that this should be marked as a duplicate as I see this as different problem. Titles are similiar, yes.

0

2 Answers 2

3

You must pass the instance from which you want to get the value.

First you have to get memberAField.GetValue(classA) so you have the value of the field, equivalent to classA.classAA. Then call get value using this result classAProperty.GetValue(memberAField.GetValue(classA)), equivalent to classA.classAA.PeropertyA.

        Console.WriteLine(" to value: " + classAProperty.GetValue(memberAField.GetValue(classA)));

Full code :

classA classA = new classA();
classA.classAA.propertyA = "A";
classA.classAB.propertyB = "B";

foreach (FieldInfo memberAField in classA.GetType().GetFields()) {
    Console.WriteLine(memberAField.Name + " " + memberAField.MemberType + " " + memberAField.FieldType);
    object memberAValue = memberAField.GetValue(classA);
    foreach (PropertyInfo classAProperty in memberAField.FieldType.GetProperties()) {
        Console.WriteLine("name: " + classAProperty.Name);
        if (memberAValue == null)
            Console.WriteLine(" no value available");
        else
            Console.WriteLine(" to value: " + classAProperty.GetValue(memberAValue));
        }
    }
2

GetValue requires an object instance for which you are getting the property value, so you just need to call FieldInfo.GetValue on the initial object:

foreach (FieldInfo memberAField in classA.GetType().GetFields()) {
    Console.WriteLine(memberAField.Name + " " + memberAField.MemberType + " " + memberAField.FieldType);

    object memberAValue = memberAField.GetValue(classA);  // instance to call GetValue on later.

    foreach (PropertyInfo classAProperty in memberAField.FieldType.GetProperties()) {
        Console.WriteLine("name: " + classAProperty.Name);
        Console.WriteLine(" to value: " + classAProperty.GetValue(memberAValue));
        }
    }

Not the answer you're looking for? Browse other questions tagged or ask your own question.