C# Используя Отражение для Получения Родового объекта (и его Вложенные объекты) Свойства

Это - сценарий, созданный, чтобы помочь понять то, чего я пытаюсь достигнуть.

Я пытаюсь создать метод, который возвращает указанное свойство родового объекта

например.

public object getValue<TModel>(TModel item, string propertyName) where TModel : class{
    PropertyInfo p = typeof(TModel).GetProperty(propertyName);
    return p.GetValue(item, null);
}

Код выше хорошо работает при поиске свойства на TModel item например.

string customerName = getValue<Customer>(customer, "name");

Однако, если Вы хотите узнать, каково имя группы клиента, это становится проблемой: например.

string customerGroupName = getValue<Customer>(customer, "Group.name");

Надеясь кто-то может дать мне некоторое понимание на этом сценарии выхода - спасибо.

9
задан Jimbo 26 May 2010 в 11:45
поделиться

4 ответа

В пространстве имен System.Web.UI есть способ сделать это:

DataBinder.Eval(source, expression);
3
ответ дан 4 December 2019 в 12:16
поделиться

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

// First get the customer group Property...
CustomerGroup customerGroup = getValue<Customer>(customer, "Group");
// Then get the name of the group...
if(customerGroup != null)
{
    string customerGroupName = getValue<CustomerGroup>(customerGroup, "name");
}
3
ответ дан 4 December 2019 в 12:16
поделиться

Так как группа является собственностью клиента, которая сама хранит имя свойства, вы также должны пойти по этому пути. Но с тех пор '.' не может быть частью имени свойства, вы можете легко использовать String.Substring для удаления первого имени свойства из строки и рекурсивного вызова вашего метода.

0
ответ дан 4 December 2019 в 12:16
поделиться

Вот простой метод, использующий рекурсию для решения вашей проблемы. Он позволяет вам перемещаться по графу объекта, передавая имя свойства, разделенное точками. Он работает как со свойствами, так и с полями.

static class PropertyInspector 
{
    public static object GetObjectProperty(object item,string property)
    {
        if (item == null)
            return null;

        int dotIdx = property.IndexOf('.');

        if (dotIdx > 0)
        {
            object obj = GetObjectProperty(item,property.Substring(0,dotIdx));

            return GetObjectProperty(obj,property.Substring(dotIdx+1));
        }

        PropertyInfo propInfo = null;
        Type objectType = item.GetType();

        while (propInfo == null && objectType != null)
        {
            propInfo = objectType.GetProperty(property, 
                      BindingFlags.Public 
                    | BindingFlags.Instance 
                    | BindingFlags.DeclaredOnly);

            objectType = objectType.BaseType;
        }

        if (propInfo != null)
            return propInfo.GetValue(item, null);

        FieldInfo fieldInfo = item.GetType().GetField(property, 
                      BindingFlags.Public | BindingFlags.Instance);

        if (fieldInfo != null)
            return fieldInfo.GetValue(item);

        return null;
    }
}

Пример:

class Person
{
   public string Name { get; set; }
   public City City { get; set; }
}

class City
{
   public string Name { get; set; }
   public string ZipCode { get; set; }
}

Person person = GetPerson(id);

Console.WriteLine("Person name = {0}", 
      PropertyInspector.GetObjectProperty(person,"Name"));

Console.WriteLine("Person city = {0}",
      PropertyInspector.GetObjectProperty(person,"City.Name"));
11
ответ дан 4 December 2019 в 12:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: