I am trying to create a recursive procedure that will retrieve PropertyInfos for all members under a specific object (in .NET 3.5). Everything for immediate members works, but you also need to parse nested classes (and their nested classes, etc.).
I don't understand how to handle a section that parses nested classes. How do you write this piece of code?
public class ObjectWalkerEntity
{
public object Value { get; set; }
public PropertyInfo PropertyInfo { get; set; }
}
public static class ObjectWalker
{
static List<ObjectWalkerEntity> objectList = new List<ObjectWalkerEntity>();
public static List<ObjectWalkerEntity> Walk(object o)
{
objectList.Clear();
processObject(o);
return objectList;
}
private static void processObject(object o)
{
if (o == null)
{
return;
}
Type t = o.GetType();
foreach (PropertyInfo pi in t.GetProperties())
{
if (isGeneric(pi.PropertyType))
{
ObjectWalkerEntity obj = new ObjectWalkerEntity();
obj.PropertyInfo = pi;
obj.Value = pi.GetValue(o, null);
objectList.Add(obj);
}
else
{
foreach (Object item in pi.PropertyType)
{
processObject(item);
}
}
}
return;
}
private static bool isGeneric(Type type)
{
return
Extensions.IsSubclassOfRawGeneric(type, typeof(bool)) ||
Extensions.IsSubclassOfRawGeneric(type, typeof(string)) ||
Extensions.IsSubclassOfRawGeneric(type, typeof(int)) ||
Extensions.IsSubclassOfRawGeneric(type, typeof(UInt16)) ||
Extensions.IsSubclassOfRawGeneric(type, typeof(UInt32)) ||
Extensions.IsSubclassOfRawGeneric(type, typeof(UInt64)) ||
Extensions.IsSubclassOfRawGeneric(type, typeof(DateTime));
}
Edit: I used some Harlam suggestions and came up with a working solution. This handles both nested classes and lists.
I replaced my previous loop through the info property with the following
foreach (PropertyInfo pi in t.GetProperties())
{
if (isGeneric(pi.PropertyType))
{
ObjectWalkerEntity obj = new ObjectWalkerEntity();
obj.PropertyInfo = pi;
obj.Value = pi.GetValue(o, null);
objectList.Add(obj);
}
else if (isList(pi.PropertyType))
{
var list = (IList)pi.GetValue(o, null);
foreach (object item in list)
{
processObject(item);
}
}
else
{
object value = pi.GetValue(o, null);
processObject(value);
}
}
I also added a new check to see if there is anything on the list.
private static bool isList(Type type)
{
return
IsSubclassOfRawGeneric(type, typeof(List<>));
}
Thanks for the help!
Ethic