在C#中常量和只读之间有什么区别?

你什么时候会用一个代替另一个?


当前回答

ReadOnly:该值只能从类的构造函数初始化一次。const:可以在任何函数中初始化,但只能初始化一次

其他回答

我们办公室的一名团队成员就何时使用常量、静态和只读提供了以下指导:

当您有一个在运行时可以知道的类型的变量(string literal、int、double、enums…),您希望类的所有实例或使用者都可以访问值不应更改的位置时,请使用const。如果您希望类的所有实例或使用者都可以访问值可以更改的数据,请使用静态。当您有一个在运行时无法知道的类型的变量(对象),您希望类的所有实例或使用者都可以访问值不应更改的位置时,请使用静态只读。当您有一个实例级变量时,您将在创建对象时知道该变量不应更改,请使用readonly。

最后一个注意事项:常量字段是静态的,但反之则不是真的。

另外,只读引用类型只会使引用只读,而不会使值只读。例如:

public class Const_V_Readonly
{
  public const int I_CONST_VALUE = 2;
  public readonly char[] I_RO_VALUE = new Char[]{'a', 'b', 'c'};

  public UpdateReadonly()
  {
     I_RO_VALUE[0] = 'V'; //perfectly legal and will update the value
     I_RO_VALUE = new char[]{'V'}; //will cause compiler error
  }
}

常量必须是硬编码的,其中可以在类的构造函数中设置为只读。

只读字段的值可以更改。但是,常量字段的值不能更改。

在只读字段中,我们可以在声明时或在该类的构造函数中赋值。如果是常量,我们只能在声明时赋值。

只读可以与静态修饰符一起使用,但常量不能与静态一起使用。

还有一个陷阱:只读值可以通过反射被“狡猾”的代码改变。

var fi = this.GetType()
             .BaseType
             .GetField("_someField", 
                       BindingFlags.Instance | BindingFlags.NonPublic);
fi.SetValue(this, 1);

我可以使用反射更改C#中的私有只读继承字段吗?