callisto
callisto

Reputation: 5083

Reflection - getting properties of nested objects

refers to : Reflection - setting Type of returned obj? I have a object Call Jobcard with a few properties, one of which is another object called Customer with its own properties, one of which is another nested object called Adress.

These 2 functions will be handling other object types as well.

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;
}

The problem is that the PopulateChildObject function does not work because the PropertyInfo list is not that of the passed childObj. If I look at the dataObj passed to PopulateChildObject in the watch, it has 0 Attributes. Also the dataObj passed to PopChildObj() has type of System.Reflection.RuntimePropertyInfo' instead of type Customer. What am I missing?

Upvotes: 2

Views: 7056

Answers (2)

Mohamed.Abdo
Mohamed.Abdo

Reputation: 2200

Get Nest properties e.g., 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]);
            }

Upvotes: 1

Marc Gravell
Marc Gravell

Reputation: 1062530

propertyitem is the PropertyInfo; you need to pass it the value from the property - i.e.

propertyItem.GetValue(dataObj, null);

If this child object is created by the parent, you shouldn't need to "set" it; just update the underyling object:

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

It may be you need to create the child object (usually Activator.CreateInstance), in which case you will need to call SetValue:

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

I wonder, though - is there really any difference between PopulateObject and PopulateChildObject? It feels like they could be the same thing?

Upvotes: 3

Related Questions