【问题标题】:C#: Accessing Inherited Private Instance Members Through ReflectionC#:通过反射访问继承的私有实例成员
【发布时间】:2010-10-15 17:57:46
【问题描述】:

我是 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.

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

【问题讨论】:

    标签: c# reflection


    【解决方案1】:

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

    【讨论】:

    • 垃圾,它们当然存在于B中。如果它们不在B中,那么从A继承的访问这种私有字段的方法如何工作?
    • B 的实例可能有 A 的私有成员,但 B 的类型不知道这些成员。
    【解决方案2】:

    没试过,不过应该可以通过Type.BaseType属性访问基类型私有成员,通过继承层次递归累加所有私有字段。

    【讨论】:

      【解决方案3】:

      正如 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”子句来忽略继承的字段。
      • 不使用类型的BaseType,我们仍然可以访问基类私有成员吗?不,这对我来说并没有解决任何现实世界的问题,但我只是好奇,因为使用 Type 类的 BaseType 属性我确信(在编写它时)我正在访问 Childs 基类成员,所以有没有其他方法不使用BaseType 属性实现一样吗?
      【解决方案4】:

      您可以使用“嵌套类”从 B 类访问 A 类的私有成员 .您将 A 类设为外部类,将 B 类设为内部类

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

      【讨论】:

      • 我无法修改课程。我只是想通过反射来获取有关它们的信息。
      猜你喜欢
      • 2011-04-03
      • 2012-01-04
      • 1970-01-01
      • 2020-09-01
      • 1970-01-01
      • 2012-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多