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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/686482/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 13:27:15  来源:igfitidea点击:

C#: Accessing Inherited Private Instance Members Through Reflection

c#reflection

提问by Odrade

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.

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

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.

这无法找到字段 Ba

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.

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

采纳答案by sisve

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

回答by Andy

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

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

回答by Lee

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.

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

回答by Balamurugan kalyanasundaram

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

您可以使用 'Nested Classes' 从 Class B 访问 Class A 的私有成员。您将 A 类设为外部类,将 B 类设为内部类

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

}