2008-10-28 2 views
22

Also, was ich jetzt habe, ist so etwas wie dieses:Wie erhalten Sie alle Eigenschaften einer Klasse und ihrer Basisklassen (nach oben) mit Reflection? (C#)

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

wo obj ist ein Objekt.

Das Problem ist, einige der Eigenschaften, die ich will, sind nicht in obj.GetType() sie sind in einer der Basisklassen weiter oben. Wenn ich den Debugger stoppe und auf obj schaue, muss ich ein paar "Basis" -Einträge durchforsten, um die Eigenschaften zu sehen, die ich bekommen möchte. Gibt es eine verbindliche Markierung, die ich setzen kann, um sie zurückgeben zu lassen, oder muss ich rekursiv durch die Type.BaseType Hierarchie graben und GetProperties auf allen von ihnen tun?

Antwort

21

verwenden:

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

EDIT: Natürlich ist die richtige Antwort, dass der Jay ist. GetProperties() ohne Parameter entspricht GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static). Die BindingFlags.FlattenHierarchy spielt hier keine Rolle.

+0

Ich bezeichne dies als die Antwort, weil, obwohl Jay arbeitet und würde mir, was ich will, dies erklärt, warum es funktioniert. Ich nahm einfach an, dass, wenn weder Instance noch Static angegeben würden, beide gleichzeitig sein würden, obwohl es tatsächlich nicht zurückgegeben wurde. – Davy8

+0

Es gab keine Top-Level-Eigenschaften in dem Objekt, das ich betrachtete, also nahm ich an, dass es nur versucht hat, die Top-Level-Eigenschaften abzurufen, wenn es nichts zurückgibt, obwohl es tatsächlich keine Eigenschaften zurückgegeben hat Statisch oder Instanz. – Davy8

4

Wenn Sie auf Type.BaseType zugreifen, können Sie den Basistyp abrufen. Sie können rekursiv auf jeden Basistyp zugreifen und Sie werden wissen, wann Sie den unteren Rand erreicht haben, wenn Ihr Typ System.Object ist.

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

liebe dich Mann. Gute Eins. Warum haben die Leute diesen gewählt? – argatxa

+0

Cool! Danke dafür. Gespeichert den Tag für statische Member in der Basisklasse. – Justjyde

12

Ich denke nicht, dass es so kompliziert ist.

Wenn Sie den BindingFlags Parameter GetProperties entfernen, ich glaube, Sie erhalten die Ergebnisse, die Sie suchen:

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

produziert

 
    MyProperty2 
    MyProperty 
2

Verwendung:

TypeDescriptor.GetProperties(obj); 
3

I würde eher Nicolas zustimmen; Wenn Sie nicht wissen, dass Sie eine Reflexion benötigen, ist ComponentModel eine praktikable Alternative, mit dem Vorteil, dass Sie selbst für Laufzeitmodelle die richtigen Metadaten erhalten (wie DataView/DataRowView).

Zum Beispiel:

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

Als Nebenwirkung, können Sie auch einige einfache performance tricks mit diesem tun; Sie können das gleiche mit Reflexion und Delegate.CreateDelegate tun, aber es gibt keinen zentralen Ort, um die Logik weg zu verstecken, im Gegensatz TypeDescriptor mit einer TypeDescriptionProvider (keine Sorge, wenn diese nicht vertraut sind; Sie können einfach den Code "wie es ist ;-p verwenden.").