Отражение - получение свойств вложенных объектов

относится к: Отражение - установка типа возвращаемого объекта? У меня есть объект Call Карточка вакансии с несколькими свойствами, одно из которых является другим объектом с именем Customer со своими собственными свойствами, одно из которых является еще одним вложенным объектом с именем Adress.

Эти две функции будут обрабатывать и другие типы объектов.

private T PopulateObject<T>(T dataObj, System.Data.DataRow dataRow)
{

    //Type type = dataObj.GetType();
    System.Reflection.PropertyInfo[] proplist = dataObj.GetType().GetProperties();

    foreach ( System.Reflection.PropertyInfo propertyitem in proplist)
    {
        if(propertyitem.Name != "")
        //s += propertyitem.Name + ":" + (propertyitem.GetValue(dataObj,null)).ToString() + "\r\n";
            try
            {
                propertyitem.SetValue(dataObj, dataRow[propertyitem.Name], null);
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("does not belong to table"))
                {
                   propertyitem.SetValue(dataObj, PopulateChildObject(propertyitem, dataRow), null);
                }
                else
                throw;
            } 
    }
    return dataObj;
}



private object PopulateChildObject(object dataObj, System.Data.DataRow dataRow)
{

    System.Reflection.PropertyInfo[] proplist = dataObj.GetType().GetProperties();

    foreach ( System.Reflection.PropertyInfo propertyitem in proplist)
    {
        if(propertyitem.Name != "")
            try
            {
                propertyitem.SetValue(dataObj, dataRow[propertyitem.Name], null);
            }
            catch (Exception ex)
            {           
             if (ex.Message.Contains("does not belong to table"))
                {
                   propertyitem.SetValue(dataObj, PopulateChildObject(propertyitem, dataRow), null);
                }
                else
                throw;
            } 
    }
    return dataObj;
}

Проблема в том, что функция PopulateChildObject не работает, поскольку список PropertyInfo не совпадает со списком переданного childObj. Если я смотрю на dataObj, переданный в PopulateChildObject в часах, он имеет 0 атрибутов. Также dataObj, переданный в PopChildObj (), имеет тип System.Reflection.RuntimePropertyInfo вместо типа Customer. Что мне не хватает?


person callisto    schedule 26.05.2009    source источник


Ответы (2)


propertyitem - это PropertyInfo; вам нужно передать ему значение из свойства - т.е.

propertyItem.GetValue(dataObj, null);

Если этот дочерний объект создается родителем, вам не нужно его «устанавливать»; просто обновите объект-подручник:

PopulateChildObject(propertyitem.GetValue(dataObj, null), dataRow);

Возможно, вам потребуется создать дочерний объект (обычно Activator.CreateInstance), и в этом случае вам нужно вызвать SetValue:

object child = propertyitem.GetValue(dataObj, null);
if(child == null) {
    child = Activator.CreateInstance(propertyitem.PropertyType);
    propertyitem.SetValue(dataObj, child, null);
}
PopulateChildObject(child, dataRow);

Интересно, правда, есть ли разница между PopulateObject и PopulateChildObject? Такое ощущение, что они могут быть одним и тем же?

person Marc Gravell    schedule 26.05.2009
comment
разница между PopulateObject и PopulateChildObject: я не мог получить рекурсивный вызов PopulateObject, работающий, потому что также должен быть передан тип дочернего объекта. - person callisto; 26.05.2009
comment
Только потому, что вы сделали его универсальным, но (согласно моему ответу на предыдущий вопрос) здесь от дженериков мало пользы. - person Marc Gravell; 26.05.2009
comment
Спасибо, Марк. Я получил это с помощью другого вашего сообщения: eggheadcafe.com/ propertyitem.PropertyType; это то, что мне нужно было сделать - person callisto; 26.05.2009

Получить свойства Nest, например Developer.Project.Name

private static System.Reflection.PropertyInfo GetProperty(object t, string PropertName)
            {
                if (t.GetType().GetProperties().FirstOrDefault(p => p.Name == PropertName.Split('.')[0]) == null)
                    throw new ArgumentNullException(string.Format("Property {0}, is not exists in object {1}", PropertName, t.ToString()));
                if (PropertName.Split('.').Length == 1)
                    return t.GetType().GetProperty(PropertName);
                else
                    return GetProperty(t.GetType().GetProperty(PropertName.Split('.')[0]).GetValue(t, null), PropertName.Split('.')[1]);
            }
person Mohamed.Abdo    schedule 26.11.2013