С#: доступ к членам унаследованного частного экземпляра посредством отражения

Я являюсь абсолютным новичком при отражении на С#. Я хочу использовать рефлексию для доступа ко всем частным полям класса, включая те, которые унаследованы.

Мне удалось получить доступ ко всем закрытым полям, за исключением тех, которые унаследованы, а также все общедоступные и защищенные унаследованные поля. Однако я не смог получить доступ к закрытым, унаследованным полям. Следующий пример иллюстрирует:

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

Это не может найти поле B.a.

Возможно ли это сделать? Очевидным решением было бы преобразовать частные, унаследованные поля в защищенные поля. Это, однако, сейчас не в моих силах.

Ответ 1

Как сказал Ли, вы можете сделать это с рекурсией.

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

Ответ 2

Я не пробовал, но вы должны иметь доступ к частным членам базового типа через свойство Type.BaseType и рекурсивно накапливать все частные поля через иерархию наследования.

Ответ 3

Вы не можете получить доступ к закрытым полям A, используя тип B, потому что эти поля не существуют в B - они существуют только в A. Вам либо нужно напрямую указать тип A, либо получить его с помощью других средств (например, получить базовый класс от типа B).

Ответ 4

Вы можете получить доступ к закрытым членам класса A из класса B с помощью "Вложенных классов", , Вы делаете класс A как внешний класс и класс B как внутренний класс

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

}