如何查找成员变量是否为只读

本文关键字:变量 是否 只读 成员 何查找 查找 | 更新日期: 2023-09-27 18:06:37

class Bla
{
    public readonly int sum;
}
FieldInfo f = type.GetField("sum");
f.??   // what?

如何发现sum是否为只读?对于属性,我可以执行PropertyInfo.CanWrite来查找成员是否具有写访问权限。

如何查找成员变量是否为只读

readonly意味着字段赋值只能发生在字段声明附近或构造函数内部。因此,您可以在FieldInfo上使用IsInitOnly属性,

获取一个值,该值指示字段是否只能在构造函数的主体中设置

更多细节见IsInitOnly MSDN文章

FieldInfo f = typeof(Bla).GetField("sum");
Console.WriteLine(f.IsInitOnly); //return true

注意:您也可以使用IsLiteral属性来测试字段是否为编译时间常数。对于readonly字段,它将返回false,但是对于标记为const的字段,它将返回true。

另一个注意事项:反射不会阻止您写入readonlyprivate字段(public readonly也是如此,但我想展示一个更受限制的情况)。所以下面的代码示例是有效的,不会抛出任何异常:

class Bla
{
    //note field is private now
    private readonly int sum = 0;
}

现在,如果您获得该字段并为其写入一个值(我使用BindingFlags来获取私有非静态字段,因为GetField默认情况下不会返回私有字段的FieldInfo)

FieldInfo field = typeof(Bla).GetField("sum", BindingFlags.NonPublic |
                                              BindingFlags.Instance);
var bla = new Bla();
field.SetValue(bla, 42);
Console.WriteLine(field.GetValue(bla)); //prints 42

一切正常。只有当字段为const时,它才会抛出异常。

f.Attributes应该包含FieldAttributes.InitOnly