17

I am an absolute novice at reflection in C#. I want to use reflection to access all of private fields in a class, including those which are inherited.

I have succeeded in accessing all private fields excluding those which are inherited, as well as all of the public and protected inherited fields. However, I have not been able to access the private, inherited fields. The following example illustrates:

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

This fails to find the field B.a.

Is it even possible to accomplish this? The obvious solution would be to convert the private, inherited fields to protected fields. This, however, is out of my control at the moment.

Odrade
  • 7,409
  • 11
  • 42
  • 65

4 Answers4

14

As Lee stated, you can do this with recursion.

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);
}
sisve
  • 19,501
  • 3
  • 53
  • 95
  • Instead of the "if" clause to ignore inherited fields, you could just specify BindingFlags.DeclaredOnly. – Timwi Aug 18 '09 at 23:07
  • with out using BaseType on a Type, can we still access Base class private member. No this is not solving any real world problem for me, but i am just curious because using BaseType property of Type class i am convinced that (while writing it) i am accessing Childs base class members, so is there any way else with out using BaseType property to achieve the same? – Zenwalker Oct 19 '11 at 06:38
4

I haven't tried it, but you should be able to access the base type private members through the Type.BaseType property and recursively accumulate all the private fields through the inheritence hierarchy.

Lee
  • 1,125
  • 6
  • 7
0

You can't access the private fields of A using the type of B because those fields don't exist in B - they only exist in A. You either need to specify the type of A directly, or retrieve it via other means (such as getting the base class from the type of B).

Andy
  • 30,088
  • 6
  • 78
  • 89
  • 3
    Rubbish, of course they exist in B. If they weren't in B, how could a method inherited from A that accesses such a private field work? – Timwi Aug 18 '09 at 23:06
  • 4
    The instance of B may have A's private members, but the Type of B has no knowledge of such members. – Andy Aug 19 '09 at 02:24
-1

You can access private members of Class A from Class B with 'Nested Classes' . You make Class A as Outer Class and Class B as Inner Class

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

}
CoolBeans
  • 20,654
  • 10
  • 86
  • 101
  • 2
    I'm not able to modify the classes. I'm just trying to garner info about them via reflection. – Odrade Jun 24 '10 at 17:08