Использование отражения в C # для получения свойств вложенного объекта - PullRequest
64 голосов
/ 23 декабря 2009

Даны следующие объекты:

public class Customer {
    public String Name { get; set; }
    public String Address { get; set; }
}

public class Invoice {
    public String ID { get; set; }
    public DateTime Date { get; set; }
    public Customer BillTo { get; set; }
}

Я бы хотел использовать отражение, чтобы пройти через Invoice, чтобы получить Name свойство Customer. Вот что я хочу, предполагая, что этот код будет работать:

Invoice inv = GetDesiredInvoice();  // magic method to get an invoice
PropertyInfo info = inv.GetType().GetProperty("BillTo.Address");
Object val = info.GetValue(inv, null);

Конечно, это терпит неудачу, так как "BillTo.Address" не является допустимым свойством класса Invoice.

Итак, я попытался написать метод, чтобы разбить строку на части периода и обойти объекты в поисках окончательного значения, которое меня интересовало. Это работает хорошо, но мне это не совсем удобно:

public Object GetPropValue(String name, Object obj) {
    foreach (String part in name.Split('.')) {
        if (obj == null) { return null; }

        Type type = obj.GetType();
        PropertyInfo info = type.GetProperty(part);
        if (info == null) { return null; }

        obj = info.GetValue(obj, null);
    }
    return obj;
}

Любые идеи о том, как улучшить этот метод, или лучший способ решить эту проблему?

РЕДАКТИРОВАТЬ после публикации я увидел несколько похожих сообщений ... Однако, похоже, нет ответа, который бы конкретно касался этого вопроса. Кроме того, я все еще хотел бы получить отзыв о моей реализации.

Ответы [ 12 ]

0 голосов
/ 22 июня 2012

Мое интернет-соединение было прервано, когда мне нужно было решить ту же проблему, поэтому мне пришлось «заново изобрести колесо»:

static object GetPropertyValue(Object fromObject, string propertyName)
{
    Type objectType = fromObject.GetType();
    PropertyInfo propInfo = objectType.GetProperty(propertyName);
    if (propInfo == null && propertyName.Contains('.'))
    {
        string firstProp = propertyName.Substring(0, propertyName.IndexOf('.'));
        propInfo = objectType.GetProperty(firstProp);
        if (propInfo == null)//property name is invalid
        {
            throw new ArgumentException(String.Format("Property {0} is not a valid property of {1}.", firstProp, fromObject.GetType().ToString()));
        }
        return GetPropertyValue(propInfo.GetValue(fromObject, null), propertyName.Substring(propertyName.IndexOf('.') + 1));
    }
    else
    {
        return propInfo.GetValue(fromObject, null);
    }
}

Уверен, что это решает проблему для любой строки, которую вы используете для имени свойства, независимо от степени вложенности, если все является свойством.

0 голосов
/ 23 декабря 2009

Попробуйте inv.GetType().GetProperty("BillTo+Address");

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