2008-10-28 20 views
22

Así que lo que tengo en este momento es algo como esto:¿Cómo se obtienen todas las propiedades de una clase y sus clases base (en la jerarquía) con Reflection? (C#)

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

donde obj es un objeto.

El problema es que algunas de las propiedades que quiero no están en obj.GetType() están en una de las clases base más arriba. Si detengo el depurador y miro obj, tengo que buscar entre algunas entradas "base" para ver las propiedades que quiero obtener. ¿Hay alguna bandera de encuadernación que pueda configurar para que la devuelva o tengo que excavar recursivamente a través de la jerarquía Type.BaseType y hacer GetProperties en todas ellas?

Respuesta

21

Utilice esta:

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

EDIT: Por supuesto, la respuesta correcta es la de Jay. GetProperties() sin parámetros es equivalente a GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static). El BindingFlags.FlattenHierarchy no juega ningún papel aquí.

+0

Estoy marcando esto como la respuesta porque aunque Jay funciona y me da lo que quiero, esto explica por qué funciona. Simplemente asumí que si no se especificasen Instance ni Static, se utilizaría de manera predeterminada en ambos, cuando en realidad no devolvía ninguno. – Davy8

+0

No había propiedades de nivel superior en el objeto que estaba viendo, así que asumí que solo estaba tratando de recuperar las de nivel superior cuando no devolvía nada, cuando en realidad no devolvía nada porque estaba tratando de obtener propiedades que no eran Estático ni Instancia. – Davy8

4

Si accede al Type.BaseType, puede obtener el tipo de base. Puede acceder recursivamente a cada tipo base y sabrá cuándo ha tocado fondo cuando su tipo es System.Object.

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

te amo hombre. Buena persona ¿Por qué la gente ha votado por este? – argatxa

+0

¡Genial! Gracias por esto. Ahorró el día para miembro estático en la clase base. – Justjyde

12

No creo que sea tan complicado.

Si se quita el parámetro BindingFlags a GetProperties, creo que obtenga los resultados que usted está buscando:

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

produce

 
    MyProperty2 
    MyProperty 
2

Uso:

TypeDescriptor.GetProperties(obj); 
3

I tendería a estar de acuerdo con Nicolas; a menos que sepa que necesita reflexión, entonces ComponentModel es una alternativa viable, con la ventaja de que obtendrá los metadatos correctos incluso para los modelos de tiempo de ejecución (como DataView/DataRowView).

Por ejemplo:

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

Como acotación al margen, también se puede hacer algunos simples performance tricks con esto; puede hacer lo mismo con reflection y Delegate.CreateDelegate, pero no hay un lugar centralizado para ocultar la lógica, a diferencia de TypeDescriptor con un TypeDescriptionProvider (no se preocupe si no le resulta familiar, puede usar el código "tal cual" ;-)

Cuestiones relacionadas