4

How can I get the list of elements and datatypes of an array of an object in c# with reflections?

Scenario: I have a method with an array parameter in my web service (asmx). Using reflection I am reading the method parameters and loop through the properties. Here is my code:


Example: I have a webservice http://localhost/services/myservice.asmx. It has a method string GetServiceData(context mycontext). context class has following properties

- string name
- Account[] accounts

Account in turn has

- string acct_name
- string acct_address

I need to read the service dynamically to generate the following output

<GetServiceData>
    <mycontext>
        <name>string</name>
        <accounts>
            <acct_name>string</acct_name>
            <acct_address>string</acct_address>
        </accounts>
    </mycontext>
</GetServiceData>

To do so I am dynamically reading the MethodInfo and get all the parameters. Then I loop through the parameters to get the list of all the properties and the datatypes. If there is an array element in the properties then I need to get all the elements of that array element.

Solution (Thanks to Ani)


foreach (MethodInfo method in methods)
{
    sb.Append("<" + method.Name + ">");
    ParametetInfo parameters = method.GetParameters();
    foreach(ParameterInfo parameter in parameters)
    {
        sb.Append("<" + parameter.Name + ">");
        if (IsCustomType(parameter.ParameterType))
        {
           sb.Append(GetProperties(parameter.ParameterType));
        }
        else
        {
            sb.Append(parameter.ParameterType.Name);
        }
        sb.Append("</" + parameter.Name + ">");
    }
    sb.Append("</" + sMethodName + ">");
}

GetProperties() method reads the type and actually loop through each property and add it to string object. In this method I want to check if the property is an array then get all the elements and type for it.

public static string GetProperties(Type type)
{
    StringBuilder sb = new StringBuilder();
    foreach(PropertyInfo property in type.GetProperties())
    {
        sb.Append("<" + property.Name + ">");

        if (property.PropertyType.IsArray)
        {
            Type t = property.PropertyType.GetElementType();
            sb.Append(GetProperties(t));
        }
        else
        {
            sb.Append(property.PropertyType.name);
        }
    }
    sb.ToString();
}

2 Answers 2

9

I think you're for looking for theType.IsArray property (indicates whether a type is an array) and the Type.GetElementType method (gets, amongst other things, the element-type of an array). Do note that the element-type of the array isn't necessarily the same as the specific run-time type of each of the elements of the array; polymorphism could come into play.

Of course, to simply get the values, you can rely on array-covariance: cast the value of the property (I assume you're using PropertyInfo.GetValue somewhere) to an object[] and foreach that as usual.

EDIT:

Your update is quite confusing. If you already have an object that you think might be an array; you might as well do:

object obj = ...

object[] array = obj as object[];

if(array != null)
{
   foreach(object item in array)
   {
      ...
   }      
}

It really appears like you're confusing meta-data with real-data here. You can't actually enumerate any array if all you have is a System.Type that represents an array-type.

EDIT:

I think I've finally understood what you want to do. Just use Type.GetElementType to get the array's element-type, and then get that type's properties (recursively?). You're probably going to change your design a bit to able to get the XML output you want. XML represents a hierarchy; but your method's return-type is just a Dictionary<string, string>, which is a flat data-structure.

Sign up to request clarification or add additional context in comments.

8 Comments

Ani, I am able to check for IsArray but how can I now determine all the elements of that array type. Example: accounts is of type Account[] and it has 3 elements - acct_name (string), acct_address (string), acct_ph (string[]). how to loop through each element of accounts to add element/type in my dictionary?
@user465876: Your code sample doesn't provide any means to actually get the array: your GetProperties method accepts only a Type, which represents metadata only. As I mentioned, you probably want ProperyInfo.GetValue (with a reference to the actual object in question). Then cast the result of that call to object[]. Then you can enumerate the array with a foreach loop or similar, calling GetType() on each member in turn (after a null-check). Does that help?
@Ani, may be i am missing something here. In my code, the first snippet, I am just reading the method and the parameters. What will be the actual object there? If my method defination in WebService is something like GetServiceData(context mycontext). context type has - string name, Account[] accounts. What you mentioned will work if I am checking for the return type. I can change my GetProperties to accept a parameter of type object and then do what you mentioned. But not sure how can i do the same for parameters? I have added an example code above, please verify.
Parameters aren't the same as arguments; a MethodInfo also represents metadata only. You're going to have to actually get an object that has the real data from somewhere; I can't say where without more info.
Ani, thanks for your time here. More Info, I am trying to read the webservice (asmx) url and generate a proxy. Then I give user an ability to select a method. When user selects a method, I want to execute a code which will basically build a parameter list with datatypes. If the parameter has a custom type then I drill down further to provide that list too. I am able to read all the parameters and their hierarchy but for arrays I am getting difficulty. Now can you point me how to get an object that you mentioned?
|
1

You can check the PropertyInfo.PropertyType Property. Like this:

if (propertyInfo.PropertyType.IsArray)
{
   // Type is an array
}

Update: If you just want to get the properties of the array, you can use GetElementType like this:

    ...
    //How to check for an array??? and add it to objProp dictionary
    if (property.PropertyType.IsArray)
    {
        //??? how to read all the elements of an array 
        objProp = GetProperties(property.PropertyType.GetElementType());
    }
    ...

2 Comments

how can I now determine all the elements of that array type. Example: accounts is of type Account[] and it has 3 elements - acct_name (string), acct_address (string), acct_ph (string[]). how to loop through each element of accounts to add element/type in my dictionary?
@user - You can use Type.GetElementType() to determine the array type and just call your function again with the new type. See my update

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.