0

i need to create program that navigate an object structure and print the structure of any “struct” provided as an argument.

These "structs" are defined as follows:

  • They have only public attributes
  • Each attribute can be of the following types:
    • “Structs”
    • Primitive (e.g. int), primitive wrapper (e.g. Integer) or String

the problem is when i'm trying to print data member which is a class or struct. i'm trying to to write a recursive function that gets an object and check each field in the object: if it's a class them i send again the curr field to the same function. else i print the value of the field.

this is my code. but when i send the fieldInfo to the function the code line: ---> Type objType = i_obj.GetType();

is getting me the next value: object.GetType returned {Name = "RtFieldInfo" FullName = System.Reflection.RtFieldInfo"} System.RuntimeType

    public static void getObj(object i_obj)
    {
        Type objType = i_obj.GetType();

        FieldInfo[] objField = objType.GetFields();

        foreach (FieldInfo member in objField)
        {
            Type memberType = member.FieldType;

            if(memberType.IsClass)
            {                    
                getObj(member);
            }

            else
            {
                Console.WriteLine(member.Name + " : " + member.GetValue(i_obj));
            }

        }
    }

how can i get the real object from fieldInfo ??

avariant
  • 2,234
  • 5
  • 25
  • 33

2 Answers2

2

For the fields where IsClass is true you want to pass on the value of the field to the nested call to getObj. Also you might want to do some null checks:

public static void getObj(object i_obj)
{
    Type objType = i_obj.GetType();

    FieldInfo[] objField = objType.GetFields();

    foreach (FieldInfo member in objField)
    {
        Type memberType = member.FieldType;

        object memberValue = member.GetValue(i_obj); // <---

        if (memberValue == null)
        {
            Console.WriteLine(member.Name + " : null");
        }
        else if(memberType.IsClass)
        {                    
            getObj(memberValue); // <---
        }
        else
        {
            Console.WriteLine(member.Name + " : " + memberValue);
        }

    }
}
Jan-Peter Vos
  • 3,157
  • 1
  • 18
  • 21
  • Alternatively, since you are dealing with Types, don't pass in instances of your class objects at all. Use getObj(Type objType) as the method signature and recurse by using the member.FieldType value – avariant Feb 21 '18 at 00:26
1

When you do this:

if(memberType.IsClass)
{                    
    getObj(member);
}

you're calling the method recursively, but what you're passing back into it is member, which is a FieldInfo. So instead of looking recursively at the fields of the field's value, you're going to look at the properties of the System.Reflection.FieldInfo which I'm sure isn't what you want.

Perhaps what you want is this:

if(memberType.IsClass)
{                    
    getObj(member.GetValue(i_obj));
}

Now you're getting the value from the field - an object of some sort - and recursively calling your method with that.

I don't know what this is for, but chances are that at some point you'll need to account for collections. Presumably if the field is an array of strings you'll want to return the individual strings. Or if it's a list of some object, you'll want to iterate over the items in the list, not the members of List<T>.

Scott Hannen
  • 27,588
  • 3
  • 45
  • 62