为什么通过反射初始化字段后可以重写静态只读字段?

问题描述

我们知道,静态构造函数是在第一次调用该类时调用的。

我们现在有一个课程:

web

访问static class Demo { private readonly static int _intValue; static Demo () { _intValue = 5; } } 时将调用构造函数。值5将分配给Demo只读字段。之后,我们可以通过反射再次设置该值:

_intValue

为什么值typeof (Demo) .GetField ("_ intValue",BindingFlags.Static | BindingFlags.NonPublic) .SetValue (null,567); 可以被覆盖?它不是已经在构造函数中初始化了吗?为什么不抛出5

在NET Core 3.1中测试。完整示例https://dotnetfiddle.net/4DsJ6H

更新: 我找到了一种方法,即使在被请求一次之后也可以覆盖只读静态字段。它基于通过IL生成方法。实际上,除了原始问题之外,该替代方法如何起作用?

https://dotnetfiddle.net/oYaf5t

解决方法

反思已经打破了所有规则,包括可访问性和可变性;它实际上与unsafe一样强大:就像unsafe:如果出现问题,它是自我造成的,运行时会嘲笑您。

请注意,在.NET Core中,运行时有时会阻止您执行此操作,因为JIT优化如果您这样做会变得无效。但是,如果不在这里:很好。

注意:您以前可以通过反射更改string.Empty。想象一下,结束得如何:)