有了这个课程

class Foo
{
    // Want to find _bar with reflection
    [SomeAttribute]
    private string _bar;

    public string BigBar
    {
        get { return this._bar; }
    }
}

我想找到私有项目_bar,我将标记一个属性。这可能吗?

我已经对属性进行了此操作,我在其中查找了属性,但从未查找私有成员字段。

我需要设置哪些绑定标志来获得私有字段?


当前回答

使用BindingFlags。NonPublic和BindingFlags。实例的旗帜

FieldInfo[] fields = myType.GetFields(
                         BindingFlags.NonPublic | 
                         BindingFlags.Instance);

其他回答

是的,但是你需要设置你的绑定标志来搜索私有字段(如果你在类实例之外寻找成员)。

你需要的绑定标志是:System.Reflection.BindingFlags.NonPublic

如果你的. net框架大于4.5。您可以使用GetRuntimeFields方法。

此方法返回在指定类型上定义的所有字段,包括继承的、非公共的、实例的和静态的字段。

https://learn.microsoft.com/en-us/dotnet/api/system.reflection.runtimereflectionextensions.getruntimefields?view=net-6.0

var foo = new Foo();
var fooFields = foo.GetType().GetRuntimeFields()

带有扩展方法的漂亮语法

你可以使用如下代码访问任意类型的私有字段:

Foo foo = new Foo();
string c = foo.GetFieldValue<string>("_bar");

为此,你需要定义一个扩展方法来为你做这些工作:

public static class ReflectionExtensions {
    public static T GetFieldValue<T>(this object obj, string name) {
        // Set the flags so that private and public fields from instances will be found
        var bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
        var field = obj.GetType().GetField(name, bindingFlags);
        return (T)field?.GetValue(obj);
    }
}
typeof(MyType).GetField("fieldName", BindingFlags.NonPublic | BindingFlags.Instance)

在反射私有成员时需要注意的一件事是,如果您的应用程序运行在中等信任环境中(例如,当您运行在共享托管环境中时),它将找不到它们——BindingFlags。非公共选择将被忽略。