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

naw*_*fal 20 .net c# reflection readonly fieldinfo

class Bla
{
    public readonly int sum;
}

FieldInfo f = type.GetField("sum");
f.??   // what?
Run Code Online (Sandbox Code Playgroud)

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

Ily*_*nov 38

readonly表示字段赋值只能在字段声明附近或构造函数内部发生.所以,你可以使用IsInitOnly上的属性FieldInfo,这

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

有关MSDN文章的更多详细信息IsInitOnly

FieldInfo f = typeof(Bla).GetField("sum");
Console.WriteLine(f.IsInitOnly); //return true
Run Code Online (Sandbox Code Playgroud)

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

另一个注意事项:反射不会阻止你写入readonlyprivate字段(同样如此public readonly,但我希望显示更受限制的情况).所以下一个代码示例是有效的,不会抛出任何异常:

class Bla
{
    //note field is private now
    private readonly int sum = 0;
}
Run Code Online (Sandbox Code Playgroud)

现在,如果你得到该字段并为其写一个值(我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
Run Code Online (Sandbox Code Playgroud)

一切正常.它只会在字段为时抛出异常const.

  • +1注意到Reflection不会阻止你写一个`readonly`字段(完全违反直觉). (5认同)
  • @SamGoldberg我同意它是反直觉的,但另一方面它允许ORM工作,例如,仍然有一些很好的编译时检查. (3认同)