Я пытаюсь создать рекурсивную процедуру, которая будет извлекать PropertyInfos для всех членов указанного объекта (в .NET 3.5). Все для непосредственных членов работает, но нужно также проанализировать вложенные классы (и их вложенные классы и т. Д.).
Я не понимаю, как обращаться с разделом, который анализирует вложенные классы. Как бы вы написали эту часть кода?
public class ObjectWalkerEntity
{
public object Value { get; set; }
public PropertyInfo PropertyInfo { get; set; }
}
public static class ObjectWalker
{
// This will be the returned object
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))
{
// Add generic object
ObjectWalkerEntity obj = new ObjectWalkerEntity();
obj.PropertyInfo = pi;
obj.Value = pi.GetValue(o, null);
objectList.Add(obj);
}
else
{
////// TODO: Find a way to parse the members of the subclass...
// Parse each member of the non-generic object
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));
}
Редактировать: Я воспользовался некоторыми советами Харлама и нашел рабочее решение. Это обрабатывает как вложенные классы, так и списки.
Я заменил мой предыдущий цикл через propertyinfo следующим
foreach (PropertyInfo pi in t.GetProperties())
{
if (isGeneric(pi.PropertyType))
{
// Add generic object
ObjectWalkerEntity obj = new ObjectWalkerEntity();
obj.PropertyInfo = pi;
obj.Value = pi.GetValue(o, null);
objectList.Add(obj);
}
else if (isList(pi.PropertyType))
{
// Parse the list
var list = (IList)pi.GetValue(o, null);
foreach (object item in list)
{
processObject(item);
}
}
else
{
// Parse each member of the non-generic object
object value = pi.GetValue(o, null);
processObject(value);
}
}
Я также добавил новую проверку, чтобы увидеть, является ли что-то списком.
private static bool isList(Type type)
{
return
IsSubclassOfRawGeneric(type, typeof(List<>));
}
Спасибо за помощь!