Рекурсивно получить свойства и дочерние свойства объекта - PullRequest
13 голосов
/ 19 ноября 2010

Хорошо, так что сначала я подумал, что это достаточно просто, и, возможно, это так, и я просто слишком устал - но вот что я пытаюсь сделать. Скажем, у меня есть следующие объекты:

public class Container
{
     public string Name { get; set; }
     public List<Address> Addresses { get; set; }
}
public class Address
{
     public string AddressLine1 { get; set; }
     public string AddressLine2 { get; set; }
     public List<Telephone> Telephones { get; set; }
}
public class Telephone
{
     public string CellPhone { get; set; }
}

Что мне нужно сделать, так это «сгладить» имена свойств контейнеров в строку (включая ВСЕ дочерние свойства И дочерние свойства дочерних свойств), которая будет выглядеть примерно так:

Container.Name, Container.Addresses.AddressLine1, Container.Addresses.AddressLine2, Container.Addresses.Telephones.CellPhone

Это имеет какой-то смысл? Я не могу обернуть это вокруг своей головы.

Ответы [ 2 ]

12 голосов
/ 19 ноября 2010

Я предлагаю вам пометить все классы, которые вам нужно захватить, с пользовательским атрибутом, после этого вы можете сделать что-то вроде этого

0 голосов
/ 19 ноября 2010

Согласно моему комментарию, вы можете использовать что-то подобное, если это всегда будет общий тип List, который вы хотите связать с дочерним типом.IteratePropertiesRecursively - это итератор свойств данного типа, который будет рекурсивно перечислять свойства типа и всех дочерних типов, связанных через общий список.

protected void Test()
{
    Type t = typeof(Container);
    string propertyList = string.Join(",", IteratePropertiesRecursively("", t).ToArray<string>());
    // do something with propertyList
}

protected IEnumerable<string> IteratePropertiesRecursively(string prefix, Type t)
{
    if (!string.IsNullOrEmpty(prefix) && !prefix.EndsWith(".")) prefix += ".";
    prefix += t.Name + ".";

    // enumerate the properties of the type
    foreach (PropertyInfo p in t.GetProperties())
    {
        Type pt = p.PropertyType;

        // if property is a generic list
        if (pt.Name == "List`1")
        {
            Type genericType = pt.GetGenericArguments()[0];
            // then enumerate the generic subtype
            foreach (string propertyName in IteratePropertiesRecursively(prefix, genericType))
            {
                yield return propertyName;
            }
        }
        else
        {
            // otherwise enumerate the property prepended with the prefix
            yield return prefix + p.Name;
        }
    }
}

Примечание: Этот кодне будет правильно обрабатывать тип, который рекурсивно включает себя как тип одного из его свойств.Попытка перебрать такой тип приведет к StackOverflowException, на что указывает @Dementic (спасибо!).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...