2009-03-26 20 views
17

Soy un novato absoluto en la reflexión en C#. Quiero usar la reflexión para acceder a todos los campos privados de una clase, incluidos los heredados.C#: Accediendo a miembros de instancias privadas heredadas a través de la Reflexión

He tenido éxito al acceder a todos los campos privados, excepto los heredados, así como a todos los campos públicos y protegidos heredados. Sin embargo, no he podido acceder a los campos privados y heredados. El siguiente ejemplo ilustra:

class A 
{ 
    private string a; 
    public string c; 
    protected string d; 
} 

class B : A 
{ 
    private string b; 
} 

class test 
{ 
    public static void Main(string[] Args) 
    { 
     B b = new B();  
     Type t; 
     t = b.GetType(); 
     FieldInfo[] fields = t.GetFields(BindingFlags.Public | BindingFlags.NonPublic 
             | BindingFlags.Instance); 
     foreach(FieldInfo fi in fields){ 
      Console.WriteLine(fi.Name); 
     } 
     Console.ReadLine(); 
    } 
} 

Esto no puede encontrar el campo B.a.

¿Es posible incluso lograr esto? La solución obvia sería convertir los campos privados y heredados en campos protegidos. Esto, sin embargo, está fuera de mi control en este momento.

Respuesta

14

Como dijo Lee, puede hacerlo con recursividad.

private static void FindFields(ICollection<FieldInfo> fields, Type t) { 
    var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; 

    foreach (var field in t.GetFields(flags)) { 
     // Ignore inherited fields. 
     if (field.DeclaringType == t) 
      fields.Add(field); 
    } 

    var baseType = t.BaseType; 
    if (baseType != null) 
     FindFields(fields, baseType); 
} 

public static void Main() { 
    var fields = new Collection<FieldInfo>(); 
    FindFields(fields, typeof(B)); 
    foreach (FieldInfo fi in fields) 
     Console.WriteLine(fi.DeclaringType.Name + " - " + fi.Name); 
} 
+0

En lugar de la cláusula "if" para ignorar los campos heredados, puede especificar BindingFlags.DeclaredOnly. – Timwi

+0

sin usar BaseType en un tipo, ¿podemos acceder al miembro privado de la clase Base? No, esto no soluciona ningún problema del mundo real, pero tengo curiosidad porque al utilizar la propiedad BaseType de la clase Type estoy convencido de que (mientras lo escribo) estoy accediendo a los miembros de la clase base de Childs, así que ¿hay alguna otra forma sin usar? Propiedad BaseType para lograr lo mismo? – Zenwalker

0

No se puede acceder a los campos privados de A utilizando el tipo de B porque esos campos no existen en B - que sólo existen en A. Debe especificar el tipo de A directamente o recuperarlo por otros medios (como obtener la clase base del tipo B).

+3

basura, por supuesto que existen en B. Si no estaban en B, ¿cómo podría un método heredado de la A que accede a un trabajo de campo como privada ? – Timwi

+4

La instancia de B puede tener miembros privados de A, pero el Tipo de B no tiene conocimiento de dichos miembros. – Andy

4

No lo he intentado, pero debería poder acceder a los miembros privados de tipo base a través de la propiedad Type.BaseType y acumular recursivamente todos los campos privados a través de la jerarquía de herencia.

-1

Se puede acceder a miembros privados de la clase A de Clase B con 'clases anidadas' . Haces de clase A como de clase exterior y Clase B como clase interna

Class A 
{ 
... 
Class B 
{ 
....... 
    } 

} 
+2

No puedo modificar las clases. Solo trato de obtener información sobre ellos a través de la reflexión. – Odrade

Cuestiones relacionadas