2008-10-28 17 views
22

Donc ce que j'ai droit est maintenant quelque chose comme ceci:Comment obtenez-vous toutes les propriétés d'une classe et de ses classes de base (dans la hiérarchie) avec Reflection? (C#)

PropertyInfo[] info = obj.GetType().GetProperties(BindingFlags.Public); 

obj est un objet.

Le problème est que certaines des propriétés que je veux ne sont pas dans obj.GetType() ils sont dans l'une des classes de base plus haut. Si j'arrête le débogueur et regarde obj, je dois passer en revue quelques entrées "de base" pour voir les propriétés que je veux obtenir. Existe-t-il un indicateur de liaison que je peux définir pour qu'il me les renvoie ou dois-je creuser récursivement dans la hiérarchie Type.BaseType et faire GetProperties sur chacun d'entre eux?

Répondre

21

Utilisez ceci:

PropertyInfo[] info = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); 

EDIT: Bien sûr, la bonne réponse est celle de Jay. GetProperties() sans paramètres est équivalent à GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static). Le BindingFlags.FlattenHierarchy ne joue aucun rôle ici.

+0

Je marque ceci comme la réponse parce que bien que Jay travaille et m'obtienne ce que je veux, ceci explique pourquoi cela fonctionne. J'ai simplement supposé que si ni Instance ni Static n'étaient spécifiés, les deux seraient par défaut, alors qu'en fait, il ne retournait pas. – Davy8

+0

Il n'y avait pas de propriétés de niveau supérieur dans l'objet que je regardais, donc j'ai supposé qu'il essayait simplement de récupérer les plus hauts quand il ne renvoyait rien, alors qu'en fait il ne renvoyait rien parce qu'il essayait d'obtenir des propriétés qui n'étaient ni Statique ni instance. – Davy8

4

Si vous accédez à Type.BaseType, vous pouvez obtenir le type de base. Vous pouvez accéder récursivement à chaque type de base et vous saurez quand vous avez atteint le bas lorsque votre type est System.Object.

Type type = obj.GetType(); 
PropertyInfo[] info = type.GetProperties(BindingFlags.Public); 
PropertyInfo[] baseProps = type.BaseType.GetProperties(BindingFlags.Public); 
+2

aimez-vous l'homme. Bon. Pourquoi les gens ont rejeté celui-ci? – argatxa

+0

Cool! Merci pour cela. Enregistré le jour pour un membre statique dans la classe de base. – Justjyde

12

Je ne pense pas que ce soit si compliqué.

Si vous supprimez le paramètre BindingFlags à GetProperties, je pense que vous obtenez les résultats que vous recherchez:

class B 
    { 
     public int MyProperty { get; set; } 
    } 

    class C : B 
    { 
     public string MyProperty2 { get; set; } 
    } 

    static void Main(string[] args) 
    { 
     PropertyInfo[] info = new C().GetType().GetProperties(); 
     foreach (var pi in info) 
     { 
      Console.WriteLine(pi.Name); 
     } 
    } 

produit

 
    MyProperty2 
    MyProperty 
2

Utilisation:

TypeDescriptor.GetProperties(obj); 
3

I aurait tendance à être d'accord avec Nicolas; À moins que vous sachiez que vous avez besoin de la réflexion, alors ComponentModel est une alternative viable, avec l'avantage que vous obtiendrez les métadonnées correctes même pour les modèles d'exécution (tels que DataView/DataRowView).

Par exemple:

foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(obj)) 
    { 
     Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(obj)); 
    } 

En aparté, vous pouvez aussi faire un peu performance tricks simple avec cela; vous pouvez faire la même chose avec la réflexion et Delegate.CreateDelegate, mais il n'y a pas d'endroit centralisé pour cacher la logique, contrairement à TypeDescriptor avec TypeDescriptionProvider (ne vous inquiétez pas si elles ne vous sont pas familières, vous pouvez simplement utiliser le code "tel quel" ;-p).