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.

Sri Reddy
  • 6,832
  • 20
  • 70
  • 112
  • 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. – Adam Feb 02 '11 at 20:05
  • 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. – Sri Reddy Feb 02 '11 at 20:12

2 Answers2

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.

EvgK
  • 1,907
  • 12
  • 10
  • @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. – Sri Reddy Feb 02 '11 at 21:26
  • 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. – EvgK Feb 02 '11 at 21:33
  • @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?? – Sri Reddy Feb 02 '11 at 22:27
  • @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? – Sri Reddy Feb 04 '11 at 22:02
  • 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); – EvgK Feb 07 '11 at 09:48
  • 2. I don't understand about "ParameterInfo.ParameterType". Please describe in more details. – EvgK Feb 07 '11 at 10:02
  • 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! – Sri Reddy Feb 07 '11 at 15:22
  • 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. – EvgK Feb 07 '11 at 15:39
  • Thanks EvgK. I started a new thread http://stackoverflow.com/questions/4923995/one-method-to-read-parameters-properties-and-return-types-at-runtime-using-c. If you get chance please respond. – Sri Reddy Feb 07 '11 at 16:56
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).

JohnOpincar
  • 5,620
  • 3
  • 35
  • 38
  • 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? – JohnOpincar Feb 02 '11 at 20:31
  • 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. – JohnOpincar Feb 02 '11 at 20:32
  • 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? – Sri Reddy Feb 02 '11 at 20:43