获取PropertyInfo的递归例程

我正在尝试创建一个递归例程,它将为指定对象下的所有成员检索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 objectList = new List(); public static List 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)); } 

编辑:我已经使用了一些Harlam的建议,并提出了一个有效的解决方案。 它处理嵌套类和列表。

我用以下内容替换了我之前通过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)); } 

谢谢您的帮助!

我认为这对你有用。 这里的想法是从每次调用ProcessObject()返回一个可枚举对象,然后将这些调用滚动到调用者List

 public class ObjectWalkerEntity { public object Value { get; set; } public PropertyInfo PropertyInfo { get; set; } } public static class ObjectWalker { public static List Walk(object o) { return ProcessObject(o).ToList(); } private static IEnumerable ProcessObject(object o) { if (o == null) { // nothing here, just return an empty enumerable object return new ObjectWalkerEntity[0]; } // create the list to hold values found in this object var objectList = new List(); Type t = o.GetType(); foreach (PropertyInfo pi in t.GetProperties()) { if (IsGeneric(pi.PropertyType)) { // Add generic object var obj = new ObjectWalkerEntity(); obj.PropertyInfo = pi; obj.Value = pi.GetValue(o, null); objectList.Add(obj); } else { // not generic, get the property value and make the recursive call object value = pi.GetValue(o, null); // all values returned from the recursive call get // rolled up into the list created in this call. objectList.AddRange(ProcessObject(value)); } } return objectList.AsReadOnly(); } private static bool IsGeneric(Type type) { return IsSubclassOfRawGeneric(type, typeof(bool)) || IsSubclassOfRawGeneric(type, typeof(string)) || IsSubclassOfRawGeneric(type, typeof(int)) || IsSubclassOfRawGeneric(type, typeof(UInt16)) || IsSubclassOfRawGeneric(type, typeof(UInt32)) || IsSubclassOfRawGeneric(type, typeof(UInt64)) || IsSubclassOfRawGeneric(type, typeof(DateTime)); } private static bool IsSubclassOfRawGeneric(Type generic, Type toCheck) { while (toCheck != typeof(object)) { var cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck; if (generic == cur) { return true; } toCheck = toCheck.BaseType; } return false; } } 

看看Devscribe 。 它是开源的,并使用Reflection来迭代每种reflection类型 – 包括处理generics。