Routine récursive pour obtenir PropertyInfo

J’essaie de créer une routine récursive qui récupérera PropertyInfos pour tous les membres sous un object spécifié (dans .NET 3.5). Tout fonctionne pour les membres immédiats, mais il doit également parsingr les classes nestedes (et leurs classes nestedes, etc.).

Je ne comprends pas comment gérer la section qui parsing les classes nestedes. Comment écririez-vous cette partie du code?

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(ssortingng)) || 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: J’ai utilisé certaines des suggestions de Harlam et proposé une solution efficace. Ceci gère les classes et les listes nestedes.

J’ai remplacé ma boucle précédente dans propertyinfo par la suivante

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

J’ai également ajouté un nouveau chèque pour voir si quelque chose est une liste.

 private static bool isList(Type type) { return IsSubclassOfRawGeneric(type, typeof(List)); } 

Merci pour l’aide!

Je pense que cela fonctionnera pour vous. L’idée est de renvoyer un object énumérable de chaque appel à ProcessObject() , puis de ProcessObject() ces appels dans la List appelants 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(ssortingng)) || 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; } } 

Jetez un coup d’œil à Devscribe . Il est open source et utilise Reflection pour itérer chaque type de reflection, y compris les génériques de traitement.