Чтение элементов массива объектов с использованием отражения C # - PullRequest
4 голосов
/ 14 марта 2011

Как получить список элементов и типов данных массива объекта в c # с отражениями?

Сценарий: У меня есть метод с параметром массива в моем веб-сервисе (asmx). Используя отражение, я читаю параметры метода и перебираю свойства. Вот мой код:


Пример: У меня есть веб-сервис http://localhost/services/myservice.asmx. У него есть метод string GetServiceData(context mycontext). класс контекста имеет следующие свойства

- string name
- Account[] accounts

У аккаунта в свою очередь есть

- string acct_name
- string acct_address

Мне нужно прочитать сервис динамически, чтобы сгенерировать следующий вывод

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

Для этого я динамически читаю MethodInfo и получаю все параметры. Затем я перебираю параметры, чтобы получить список всех свойств и типов данных. Если в свойствах есть элемент массива, мне нужно получить все элементы этого элемента массива.

Решение (спасибо Ани)


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 () считывает тип и фактически просматривает каждое свойство и добавляет его в строковый объект. В этом методе я хочу проверить, является ли свойство массивом, затем получить все элементы и ввести его.

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 ]

9 голосов
/ 14 марта 2011

Я думаю, вы ищете свойство Type.IsArray (указывает, является ли тип массивом) и Type.GetElementType метод (получает, помимо прочего, тип элемента массива).Обратите внимание, что тип элемента массива не обязательно совпадает с конкретным типом времени выполнения каждого из элементов массива;В игру может войти полиморфизм.

Конечно, чтобы просто получить значения, вы можете положиться на массив-ковариацию: приведите значение свойства (я предполагаю, что вы используете PropertyInfo.GetValue где-то) в object[] и foreach, как обычно.

РЕДАКТИРОВАТЬ :

Ваше обновление довольно запутанно.Если у вас уже есть объект , который, по вашему мнению, может быть массивом;с таким же успехом вы можете сделать:

object obj = ...

object[] array = obj as object[];

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

Похоже, вы действительно путаете метаданные с реальными данными здесь.Вы не можете фактически перечислить любой массив, если все, что у вас есть, это System.Type, который представляет массив - тип .

EDIT :

Я думаю, я наконец понял, что ты хочешь сделать.Просто используйте Type.GetElementType, чтобы получить тип элемента массива, а затем получите свойства этого типа (рекурсивно?).Возможно, вы немного измените свой дизайн, чтобы получить желаемый XML-вывод.XML представляет иерархию;но тип возврата вашего метода - просто Dictionary<string, string>, который является flat структурой данных.

1 голос
/ 14 марта 2011

Вы можете проверить свойство PropertyInfo.PropertyType . Как это:

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

Обновление: Если вы просто хотите получить свойства массива, вы можете использовать GetElementType следующим образом:

    ...
    //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());
    }
    ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...