反映基类的私有字段

这是结构:

MyClass:SuperClass2

SuperClass2:SuperClass1

superClass2位于Product.Web中,SuperClass1位于.NET System.Web程序集中

我试图强制一个值进入SuperClass1上的私有bool字段。 但无论我尝试什么,我都无法让领域从反思中回归。

我使用以下代码与不同的BindingFlag组合,但到目前为止没有任何工作。 SuperClass1是一个抽象类。

((SuperClass1)this).GetType().GetFields(System.Reflection.BindingFlags.NonPublic); 

注意:当我使用GetProperties()时,我得到了一个很好的大列表,但是当我指定任何bindingflags时,即使有匹配的属性,我也什么也得不到。 这是怎么回事?

此外,该字段未标记为内部

显然我会使用GetField(字符串名称,BindingFlags),但我甚至无法使GetFlags()工作。

更新 :我已经尝试按照建议添加BindingFlags.Instance,但它不起作用(无论如何都是预期的)。 我找回了来自SuperClass1类inheritance自的2个字段。 与GetField一起使用时返回null(字符串名称,标志)

这是我试图获取该字段的基类的代码

 public abstract class BaseValidator : Label, IValidator { private bool propertiesChecked; ... } 

您可以手动进入inheritance链以获取基本字段:

鉴于这些类:

 class SuperClass1 { private int myField; } class SuperClass2 : SuperClass1 { } class MyClass : SuperClass2 { } 

这应该工作:

 var myObj = new MyClass(); var myField = typeof(MyClass).BaseType .BaseType .GetField("myField", BindingFlags.Instance | BindingFlags.NonPublic); 

在这个SO答案中有一个更通用的解决方案: 没有从GetType()获取字段。具有BindingFlag.Default的GetFields

与BrokenGlass的解决方案类似,你可以这样做,使它更通用:

 class Base { private int _baseField; } class Derived : Base { } class Mine : Derived { } 

然后:

 Type t = typeof(Mine); FieldInfo fi = null; while (t != null) { fi = t.GetField("_baseField", BindingFlags.Instance | BindingFlags.NonPublic); if (fi != null) break; t = t.BaseType; } if (fi == null) { throw new Exception("Field '_baseField' not found in type hierarchy."); } 

作为一种实用方法:

 public static void SetField(object target, string fieldName, object value) { if (target == null) { throw new ArgumentNullException("target", "The assignment target cannot be null."); } if (string.IsNullOrEmpty(fieldName)) { throw new ArgumentException("fieldName", "The field name cannot be null or empty."); } Type t = target.GetType(); FieldInfo fi = null; while (t != null) { fi = t.GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic); if (fi != null) break; t = t.BaseType; } if (fi == null) { throw new Exception(string.Format("Field '{0}' not found in type hierarchy.", fieldName)); } fi.SetValue(target, value); } 

然后:

 Mine m = new Mine(); SetField(m, "_baseField", 10); 

我认为你需要添加System.Reflection.BindingFlags.Instance标志。 使用| 将它与NonPublic标志结合起来。

编辑:

看起来像BrokenGlass是对的。 我写了以下快速测试。

 var fields = test.GetType().BaseType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic); foreach (var field in fields) { System.Console.WriteLine(field.Name); } 

它会正确报告您要查找的字段。 (测试来自BaseValidator)

扩展方法:

 ///  /// Returns the FieldInfo matching 'name' from either type 't' itself or its most-derived /// base type (unlike 'System.Type.GetField'). Returns null if no match is found. ///  public static FieldInfo GetPrivateField(this Type t, String name) { const BindingFlags bf = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly; FieldInfo fi; while ((fi = t.GetField(name, bf)) == null && (t = t.BaseType) != null) ; return fi; } 

如果层次结构是静态的,最简单的方法是:

 var field = typeof(SuperClass1).GetField("_privateBaseField",System.Reflection.BindingFlags.NonPublic);