8

今天找到一篇文章,其中一个const字段称为编译时常量,而一个readonly字段称为运行时常量。这两个短语来自《Effective C#》。我在 MSDN 和语言规范中进行了搜索,没有找到关于runtime constant的信息。

没有冒犯,但我不认为运行时常数是一个合适的短语。

private readonly string foo = "bar";

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

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

4

5 回答 5

10

我相信作者的意思如下:

考虑示例:

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. 这是运行时常量的含义

于 2012-07-04T06:49:42.307 回答
6

正如您自己注意到的那样,该术语未在语言规范等中使用。所以;怪那本书!我将其称为“只读字段”,因为这就是它的本质——此处“只读”的定义与初始化程序/构造函数有关,并且仅限于常规代码。例如,即使是只读字段也是可变的......

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

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

(对对象执行此操作的更真实原因与反序列化有关)

于 2012-07-04T06:43:48.747 回答
2

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

此处快速总结不同之处

于 2012-07-04T06:39:44.000 回答
2

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

于 2012-07-04T06:41:31.917 回答
0

const对比readonly

这是和之间的完整简历比较:constreadonly

|-----------------------------------------|-----------------------------------------|
|              Constant Field             |             Read-only Field             |
|-----------------------------------------|-----------------------------------------|
| Compile-time constant                   | Run-time constant                       |
|-----------------------------------------|-----------------------------------------|
| Assigned to an expression evaluated at  | Assigned to any valid expression at     |
| compile time                            | runtime                                 |
|-----------------------------------------|-----------------------------------------|
| Assigned on declaration                 | Assigned on declaration or constructor  |
|-----------------------------------------|-----------------------------------------|
| Only number, Boolean or string          | Any data type                           |
|-----------------------------------------|-----------------------------------------|
| Always static                           | Optionally static                       |
|-----------------------------------------|-----------------------------------------|

解释

  • 常量是静态的(不需要实例化类来访问它们)。
  • 常量只能在声明时赋值。
  • 常量是编译时常量,因为它们被分配给在编​​译时评估的表达式:当它们改变时,应该重新编译项目以使用新值。
  • 只读字段是类中的变量,它保存一个初始化的值(仅在构造函数或声明中),然后不更改。
  • 只读字段是运行时常量,因为它们可以在运行时分配给任何有效的表达式。
  • 只读字段适用于对象的实例,但不适用于该实例的属性。所以其他代码可以改变只读字段的实例属性。
  • 只读字段是可选的静态的(如果你想让它们被所有实例共享)。

何时使用const,何时使用readonly

  • 当常量是简单类型并且它们的值永远不会改变时,它们很有用。
  • 只读字段在从源(文件、数据库或其他代码等)初始化时很有用,但它们不会被更改。
于 2019-04-26T08:11:20.407 回答