const与readonly

今天我发现了一篇文章,其中const字段称为编译时常量,readonly字段称为运行时常量 。 这两个短语来自“Effective C#”。 我在MSDN和语言规范中搜索,找不到运行时常量

没有攻击性,但我不认为运行时常量是一个恰当的短语。

 private readonly string foo = "bar"; 

创建一个名为“foo”的变量,其值为“bar”,值为readonly,这里它是一个变量,没有constant业务。 只读变量仍然是变量,它不能是常量。 变量和常量是互斥的。

也许这个问题太过分了,我还是想听别人的意见。 你怎么看?

正如您自己所说,该术语未在语言规范等中使用。 责备那本书! 我将其称为“只读字段”,因为它就是这样 – 这里“readonly”的定义与初始化器/构造函数有关,并且仅限于常规代码 。 例如,即使只读字段也是可变的……

 // how to annoy your colleagues... typeof(string).GetField("Empty").SetValue(null, " "); 

(注意,这不再适用于最近的CLR版本 – JIT可能会用ldstr替换字段加载 – 但它确实在很长一段时间内完成了)

(更真实的理由在对象上执行此操作与反序列化有关)

我相信作者的意思如下:

考虑示例:

 public class A { public const int a = Compute(); private static int Compute(){ /*some computation and return*/ return some_computed_value; } } 

这个, 不会编译,因为你必须有一个常量值来分配给a 。 所以这是 编译时常 的含义。

相反,如果你改变它

 public class A { public readonly int a = Compute(); private static int Compute(){ /*some computation and return*/ return some_computed_value; } } 

编译。 它在运行时进行计算并将其分配给a 。 这是运行时常量的含义

只读变量只能在其构造函数中更改,并且可以在复杂对象上使用。 常量变量不能在运行时更改,但只能用于简单类型,如Int,Double,String。 运行时常量有点准确,但是混淆了问题,常量和只读之间存在非常明显的差异,因此命名类似于另一个可能不是一个好主意,即使它们通常用于相同的目的。

这里差异的快速摘要

我将readonly称为“一次写入变量” ,由编译器检查,而不是在运行时。 您可以使用reflection编写该字段,因此它在运行时不是常量。