Using reflection read properties of an object containing array of another object
Asked Answered
A

2

12

How can I read the properties of an object that contains an element of array type using reflection in c#. If I have a method called GetMyProperties and I determine that the object is a custom type then how can I read the properties of an array and the values within. IsCustomType is method to determine if the type is custom type or not.

public void GetMyProperties(object obj) 
{ 
    foreach (PropertyInfo pinfo in obj.GetType().GetProperties()) 
    { 
        if (!Helper.IsCustomType(pinfo.PropertyType)) 
        { 
            string s = pinfo.GetValue(obj, null).ToString(); 
            propArray.Add(s); 
        } 
        else 
        { 
            object o = pinfo.GetValue(obj, null); 
            GetMyProperties(o); 
        } 
    } 
}

The scenario is, I have an object of ArrayClass and ArrayClass has two properties:

-string Id
-DeptArray[] depts

DeptArray is another class with 2 properties:

-string code 
-string value

So, this methods gets an object of ArrayClass. I want to read all the properties to top-to-bottom and store name/value pair in a dictionary/list item. I am able to do it for value, custom, enum type. I got stuck with array of objects. Not sure how to do it.

Adversative answered 2/2, 2011 at 19:58 Comment(2)
Hi, I dont see from your code what you are trying to achieve. The code wont compile, because pInfo.GetValue returns an object, not a string.Gebelein
Sorry about it. I have edited the code to add ToString() to pInfo.GetValue(). I had to make this method up. Originally the method has some complex logic. To simplify, I need to read all the properties, property's property and their value.Adversative
E
16

Try this code:

public static void GetMyProperties(object obj)
{
  foreach (PropertyInfo pinfo in obj.GetType().GetProperties())
  {
    var getMethod = pinfo.GetGetMethod();
    if (getMethod.ReturnType.IsArray)
    {
      var arrayObject = getMethod.Invoke(obj, null);
      foreach (object element in (Array) arrayObject)
      {
        foreach (PropertyInfo arrayObjPinfo in element.GetType().GetProperties())
        {
          Console.WriteLine(arrayObjPinfo.Name + ":" + arrayObjPinfo.GetGetMethod().Invoke(element, null).ToString());
        }
      }
    }
  }
}

I've tested this code and it resolves arrays through reflection correctly.

Eris answered 2/2, 2011 at 21:18 Comment(9)
@evgk, I can't explictly cast to DeptArray. I determine the type at runtime. The method parameter "obj" can have any class object. I need a generic method to check for arrays and iterate through it's element.Adversative
Or, there are no problems, I've modified the answer. Now it will get all arrays in passed object and will iterate through each array element and its properties without explictly casting. You can also make this method recursive if you want to.Eris
@Evgk, Brilliant! this is perfect - Thanks, I will test the logic with different object properties to see if it fail somewhere. When you say recursive, is it to check if the properties of an array has array within??Adversative
@EvgK, two followup questions: 1. How to get the values if obj is string[] or int[] or any value type array? obj.GetType().GetProperties() never returns anything. 2. Can you tell me how to change the above method that accepts a parameter of type "ParameterInfo.ParameterType" instead of obj? What should I pass in getMethod.Invoke() then?Adversative
1. That is not because of value type but because int type, for example, doesn't have any properties at all. So you should just use object itself, without enumerating through it's properties (like Console.WriteLine(element);Eris
2. I don't understand about "ParameterInfo.ParameterType". Please describe in more details.Eris
thanks EvgK for the explanation. I was able to implement 1. For 2, I am planning to use the above method for displaying the properties of a method parameters and also use it to display the properties of return type. This method works fine for return types. But to display all the properties for the method parameter, I want to pass ParameterInfo.ParameterType and it should recursively get me all properties. Do you think I should start another thread to explain it in more details? Your help is appreciated!Adversative
Tried to understand but its still not clear for me :) What is the starting point? Maybe you should indeed start a new topic and provide us with signature of the method you want and maybe some pseudo code to make it more clear.Eris
Thanks EvgK. I started a new thread #4924495. If you get chance please respond.Adversative
D
0

You'll need to retrieve the property value object and then call GetType() on it. Then you can do something like this:

var type = pinfo.GetGetMethod().Invoke(obj, new object[0]).GetType();
if (type.IsArray)
{
    Array a = (Array)obj;
    foreach (object arrayVal in a)
    {
        // reflect on arrayVal now
        var elementType = arrayVal.GetType();
    }
}

FYI -- I pulled this code from a recursive object formatting method (I would use JSON serialization for it now).

Davies answered 2/2, 2011 at 20:11 Comment(3)
No, I mean GetGetMethod. Why would you call GetSetMethod? Aren't you trying to read the property and if it's an array of DeptArray iterate over the elements and read them?Davies
I'm trying to answer this question "How can I read the properties of an object that contains an element of array type using reflection in c#." If that's not the question, then you should edit it.Davies
John, You are absolutly right that I need to read the property and iterate over DeptArray. When I run this piece of code. I get casting error at Array a = (Array)obj. It says ARrayClass canot be casted to Array. Do you think I missed something to tell?Adversative

© 2022 - 2024 — McMap. All rights reserved.