const与readonly

时间:2012-07-04 06:36:10

标签: c# .net const readonly

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

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

private readonly string foo = "bar";

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

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

5 个答案:

答案 0 :(得分: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。 这是运行时常量

的含义

答案 1 :(得分:6)

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

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

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

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

答案 2 :(得分:2)

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

差异的快速摘要here

答案 3 :(得分:2)

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

答案 4 :(得分:0)

In [1]: import networkx as nx In [2]: G = nx.path_graph(3) In [3]: nx.set_edge_attributes(G,'B', '_type') In [4]: G.add_edge(2, 3, _type="A") In [5]: SG = G.subgraph([1,2,3]) In [6]: to_remove = [(a,b) for a,b,c in SG.edges(data=True) if c['_type']=="A"] In [6]: to_remove Out[6]: [(2, 3)] In [7]: SG.remove_edges_from(to_remove) In [8]: SG.edges(data=True) Out[8]: EdgeDataView([(1, 2, {'_type': 'B'})]) const

这是一个{em> complete ,用于恢复readonlyconst之间的比较:

readonly

说明

  • 常量是静态的(无需实例化类即可访问它们)。
  • 只能在声明时分配常量。
  • 常量是编译时常量,因为它们被分配给在编​​译时求值的表达式:更改常量时,应将项目重新编译为使用新值。
  • 只读字段是类中的变量,它们包含一个已初始化的值(仅在构造函数或声明中),并且未更改。
  • 只读字段是运行时常量,因为可以在运行时将它们分配给任何有效的表达式。
  • 一个只读字段应用于该对象的实例,但不适用于该实例的属性。因此,其他代码可以更改只读字段的instance属性。
  • 只读字段(可选)是静态的(如果要使它们被所有实例共享)。

何时使用|-----------------------------------------|-----------------------------------------| | 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

    它们是简单类型并且它们的值永远不会更改时,
  • 常量很有用。
  • 只读字段在从源(文件,数据库或其他代码,.. etc。)中初始化字段时很有用,但随后将不会更改。