【发布时间】:2013-03-31 14:14:59
【问题描述】:
class Bla
{
public readonly int sum;
}
FieldInfo f = type.GetField("sum");
f.?? // what?
如何确定sum 是否为只读?对于属性,我可以通过PropertyInfo.CanWrite 查找成员是否具有写入权限。
【问题讨论】:
标签: c# .net reflection readonly fieldinfo
class Bla
{
public readonly int sum;
}
FieldInfo f = type.GetField("sum");
f.?? // what?
如何确定sum 是否为只读?对于属性,我可以通过PropertyInfo.CanWrite 查找成员是否具有写入权限。
【问题讨论】:
标签: c# .net reflection readonly fieldinfo
readonly 表示字段赋值只能发生在字段声明附近或构造函数内部。所以你可以在FieldInfo 上使用IsInitOnly 属性,
获取一个值,该值指示该字段是否只能在构造函数的主体中设置
更多详情请见IsInitOnly MSDN article
FieldInfo f = typeof(Bla).GetField("sum");
Console.WriteLine(f.IsInitOnly); //return true
注意:您也可以使用IsLiteral 属性来测试该字段是否为编译时间常数。对于readonly 字段,它将返回false,但对于标有const 的字段,它将返回true。
另一个注意事项:反射不会阻止您写入readonly 和private 字段(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时才会抛出异常。
【讨论】:
NonPublic 标志在这里做什么吗?
GetField 默认不会返回私有字段。您需要明确设置
private 的例子。谢谢
readonly 字段(这完全违反直觉)。
f.Attributes 应该包含FieldAttributes.InitOnly
【讨论】: