在.NET中,为什么常量在编译时而不是在JIT时进行评估?

今天,当我在静态类中更改公开可见常量的值,然后用新编译的版本替换了程序集的旧副本时,我有点意外。 令人惊讶的是,引用程序集的现有程序没有获取常量的新值。 也就是说,我没有重新编译可执行文件,而只是替换了那个程序集。

我的实验的完整描述是如何常数是常数?

我承认对这种行为感到非常惊讶。 我明白发生了什么,但我不明白为什么 。 是否有一个特殊的技术原因导致常量不能在JIT时间而不是编译时间被选中? 有没有这样做会破坏事情的情况?

常量应该是不变的一直以来 。 常数就像pi的值,或者是铅primefaces中的质子数。

如果你的不断变化, 它实际上并不是一个常数 ; 请改用readonly字段。

另请参阅框架设计指南,其中指出:

对永远不会改变的常量使用常量字段。 编译器将const字段的值直接烧写到调用代码中。 因此,在没有破坏兼容性的风险的情况下,永远不能更改const值。

本质上,更改常量而不重新编译依赖于它的所有内容,就像更改方法的签名而不重新编译依赖于它的所有内容一样。 编译器在编译依赖程序集时,“引入”有关元数据的信息的各种假设。 如果你做了任何改变,你不能指望事情只是继续工作。

还有第三种声明“常量”的方法:公共静态属性。

public static string ConstString {get{return "First test";}} 

这具有只读字段的版本控制语义,但如果抖动内联getter,则它变为jit-time常量。 与const不同,它可以用于用户定义的类型。

我认为对值类型和字符串使用静态属性是个好主意,但对于用户定义的类则不是,因为您不希望在每个属性访问上分配新实例。

我在我的FixedPoint类型中使用了这个,如下所示:

 public struct FixedPoint { private int raw; private const fracDigits=16; private FixedPoint(int raw) { this.raw=raw; } public static FixedPoint Zero{get{return new FixedPoint();}} public static FixedPoint One{get{return new FixedPoint(1<