反映基类的私有字段

Dus*_*vis 24 .net c# reflection

这是结构:

MyClass:SuperClass2

SuperClass2:SuperClass1

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

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

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

((SuperClass1)this).GetType().GetFields(System.Reflection.BindingFlags.NonPublic);
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

public abstract class BaseValidator : Label, IValidator
  {
    private bool propertiesChecked;
...
}
Run Code Online (Sandbox Code Playgroud)

Bro*_*ass 35

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

鉴于这些类:

class SuperClass1
{
    private int myField;
}

class SuperClass2 : SuperClass1
{
}

class MyClass : SuperClass2
{

}
Run Code Online (Sandbox Code Playgroud)

这应该工作:

var myObj = new MyClass();
var myField = typeof(MyClass).BaseType
                             .BaseType
                             .GetField("myField", BindingFlags.Instance | BindingFlags.NonPublic);
Run Code Online (Sandbox Code Playgroud)

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


Gle*_*den 8

扩展方法:

/// <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;
}
Run Code Online (Sandbox Code Playgroud)


Shi*_*umi 7

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

class Base { private int _baseField; }
class Derived : Base { }
class Mine : Derived { }
Run Code Online (Sandbox Code Playgroud)

然后:

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.");
}
Run Code Online (Sandbox Code Playgroud)

作为一种实用方法:

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);
}
Run Code Online (Sandbox Code Playgroud)

然后:

Mine m = new Mine();

SetField(m, "_baseField", 10);
Run Code Online (Sandbox Code Playgroud)