反映基类中的私有字段



结构如下:

MyClass: SuperClass2

SuperClass1

superClass2在Product中。Web和SuperClass1是在。net系统。Web会议

我试图在SuperClass1上强制一个值为私有bool字段。但是不管我怎么做,我都不能从反射中得到字段。

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

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

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

同时,该字段没有被标记为内部

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

更新:我已经尝试添加BindingFlags。实例的建议,但它不工作(无论如何预期)。我得到2个字段是从类SuperClass1继承的。与GetField(string name, Flags)一起使用时返回null

下面是基类的代码,我试图获得

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

您可以手动在继承链中向上获取基本字段:

给定这些类:

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()中获取字段。GetFields with BindingFlag。默认的

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

扩展方法:

/// <summary>
/// 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.
/// </summary>
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;
}

我认为你需要添加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);
}

正确报告您正在查找的字段。

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

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

相关内容

  • 没有找到相关文章

最新更新