C#: 通过反射访问继承的私有实例成员

17

我在C#反射方面是个绝对的新手。我想使用反射来访问类中的所有私有字段,包括继承的字段。

我已经成功访问了除继承的私有字段之外的所有私有字段,以及所有公共和受保护的继承字段。但是,我无法访问继承的私有字段。以下示例说明了这个问题:

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。

这个问题有解决的可能吗?显而易见的解决方案是将私有继承字段转换为受保护的字段。然而,目前我无法控制这一点。

4个回答

14
正如Lee所说,你可以使用递归来完成这个任务。
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);
}

你可以使用BindingFlags.DeclaredOnly而不是“if”语句来忽略继承的字段。 - Timwi
在一个类型上不使用BaseType,我们是否仍然可以访问基类的私有成员呢?这并没有解决我的实际问题,但是我只是好奇,因为在使用Type类的BaseType属性时,我相信(在编写代码时)我正在访问子类的基类成员,那么有没有其他方式可以实现同样的效果而不使用BaseType属性呢? - Zenwalker

4

我没有尝试过,但是您应该能够通过Type.BaseType属性访问基础类型的私有成员,并通过继承层次递归地累积所有私有字段。


0

你无法使用B的类型访问A的私有字段,因为这些字段不存在于B中 - 它们只存在于A中。你需要直接指定A的类型,或通过其他方式检索它(例如从B的类型获取基类)。


3
废话,当然它们存在于B中。如果它们不在B中,那么如何从A继承的方法访问这样一个私有字段呢? - Timwi
4
B的实例可能具有A的私有成员,但B的类型对这些成员一无所知。 - Andy

-1

你可以使用“嵌套类”从Class B访问Class A的私有成员。将Class A作为外部类,Class B作为内部类。

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

}

2
我无法修改这些类。 我只是试图通过反射收集有关它们的信息。 - Odrade

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接