【问题标题】:How do I change the value of a static readonly field using reflection in c#?如何在 c# 中使用反射更改静态只读字段的值?
【发布时间】:2012-02-03 13:46:20
【问题描述】:

fieldInfo 类中的 SetFields 方法将对象作为第一个参数。有没有办法在 C# 中使用反射来更改静态只读字段的值?

目前为止

var field = typeof(ClassName).GetField("FieldName",BindingFlags.Instance|BindingFlags.NonPublic);

【问题讨论】:

  • 您为什么要这样做?如果是您的代码,请不要将其声明为静态只读。如果不是,您可能会破坏某些东西。
  • @Richard 虽然确实存在 种情况,您希望能够“不正确地”处理事情。此外,如果 kunj2aan试图绕过系统,他会是怎样的黑客?

标签: c# reflection readonly


【解决方案1】:

如果你想获得一个静态字段,那么你应该使用BindingFlags.Static 而不是BindingFlags.Instance,因为后者是实例字段。

然后您可以使用field.SetValue(null, newValue) 设置该值。请注意,null 可以作为目标参数传递,因为不需要对象实例。假设您有足够的权限,反射会很高兴地更改只读字段的值。

【讨论】:

  • 我遇到了一个有趣的情况,field.GetValue(null) 返回新值,但直接访问字段(例如 Trace.WriteLine(FieldName))返回旧值。
  • 格雷格,你试过这个吗?因为,我得到了不同的结果。我可以通过这种方式设置只读实例字段,但不能设置只读静态字段。
  • 它大概适用于两年前我尝试过的任何版本的运行时。但是很明显,您不应该这样做,它违反了您与运行时的合同,并且对运行时的任何更新都可能使其停止工作。我猜他们有!
  • 我在调试时遇到了这个问题。调试器显示更新后的值,但程序继续使用旧值。也许这与 JIT 有关。
  • @AlexDev:JIT 将尝试优化它可以直接编码成汇编语言的只读值(charint 等),因此当时字段的值您的方法首先被调用将在应用程序的其余生命周期中持续存在。 See this
【解决方案2】:

你已经接近了。您的 BindingFlag 不正确。 Instance 表示实例字段,而应使用BindingFlags.Static

var field = typeof(ClassName).GetField("FieldName",BindingFlags.Static|BindingFlags.NonPublic);

【讨论】:

    猜你喜欢
    • 2013-08-06
    • 2019-06-20
    • 1970-01-01
    • 2011-03-19
    • 1970-01-01
    • 2010-11-26
    • 1970-01-01
    相关资源
    最近更新 更多