协慌网

登录 贡献 社区

const 和 readonly 有什么区别?

constreadonly之间的区别是什么?你用另一个吗?

答案

除了明显的差异

  • 必须在const VS 的定义时声明值readonly值可以动态计算,但需要在构造函数退出之前分配.. 之后它被冻结。
  • 'const 是隐含的static 。您使用ClassName.ConstantName表示法来访问它们。

有一个微妙的区别。考虑在AssemblyA定义的类。

public class Const_V_Readonly
{
  public const int I_CONST_VALUE = 2;
  public readonly int I_RO_VALUE;
  public Const_V_Readonly()
  {
     I_RO_VALUE = 3;
  }
}

AssemblyB引用AssemblyA并在代码中使用这些值。编译时,

  • const值的情况下,它就像一个 find-replace,值 2 被 '烘焙' 到AssemblyB的 IL 中。这意味着如果明天我将来会将I_CONST_VALUE更新为 20。 AssemblyB仍然会有 2,直到我重新编译它
  • readonly值的情况下,它就像是对内存位置的ref 。该值未包含在AssemblyB的 IL 中。这意味着如果更新内存位置, AssemblyB将获取新值而无需重新编译。因此,如果I_RO_VALUE更新为 30,则只需构建AssemblyA 。所有客户端都不需要重新编译。

因此,如果您确信常量的值不会更改,请使用const

public const int CM_IN_A_METER = 100;

但是如果你有一个可能改变的常数(例如精确度)...... 或者有疑问时,请使用readonly

public readonly float PI = 3.14;

更新:Aku 需要提一下因为他首先指出了这一点。另外我需要插上我学到的东西.. 有效的 C# - 比尔瓦格纳

有一个充满争议的问题!如果从另一个程序集引用常量,则其值将被编译到调用程序集中。这样,当您更新引用的程序集中的常量时,它将不会在调用程序集中更改!

常量

  • 常量默认为静态
  • 它们必须在编译时有一个值(你可以有例如 3.14 * 2,但不能调用方法)
  • 可以在函数内声明
  • 被复制到使用它们的每个程序集中(每个程序集都获取值的本地副本)
  • 可以在属性中使用

只读实例字段

  • 必须具有设置值,在构造函数退出时
  • 在创建实例时进行评估

静态只读字段

  • 在代码执行遇到类引用时(在创建新实例或执行静态方法时)进行评估
  • 在静态构造函数完成时必须具有计算值
  • 不建议将 ThreadStaticAttribute 放在这些上(静态构造函数将仅在一个线程中执行,并将为其线程设置值; 所有其他线程将使此值未初始化)