解释 C# 中 const 和 readonly 关键字之间的区别
在 C# 中,const 和 readonly 关键字均用于定义不可变值,这些值一旦声明就无法修改。但是,两者之间存在一些重要区别。
const
const 修饰符声明在编译时已知且不会更改的常量值,即它们是不可变的。在 C# 中,您只能将内置类型标记为 const。用户定义的类型(如类、结构等)不能是 const。此外,类成员类型(如方法、属性或事件)不能标记为常量。
您必须在声明期间初始化常量。
class Period{ public const int hours = 12; public const int minutes = 60; }
常量可以用任何可见性修饰符标记,即 private、public、protected、protected internal 或 private protected。
常量也充当静态值,即常量的值对于类的所有实例都是相同的。您不必用 static 关键字明确标记它们。您不能使用该类的实例变量访问常量,而必须使用类名。
readonly
标记为 readonly 的字段只能在声明期间或构造函数中分配。一旦创建了类的实例,您就无法修改 readonly 字段。
如果字段是值类型,将其标记为 readonly 会使其不可变。另一方面,如果 readonly 字段是引用类型,那么您仍然可以更改变量引用的对象的数据。但是,您不能将该引用更改为指向新对象。
class Person{ private readonly string _title; private readonly string _skill; public Person(string title, string skill){ _title = title; _skill = skill; } }
readonly 字段可以在字段声明和任何构造函数中多次赋值。此外,根据所使用的构造函数,它可以具有不同的值。
两者之间的一个重要区别是,在一个程序集中声明的 const 或 readonly 字段在另一个程序集中使用时会被编译。
对于 const 值,它就像一个查找-替换。常量值被"嵌入"到第二个程序集的中间语言中。这意味着,如果您更新常量,第二个程序集仍将具有第一个值,直到您重新编译它为止。
对于 readonly 值,它就像对内存位置的引用。该值不会嵌入到第二个程序集的中间语言中。这意味着,如果更新了内存位置,第二个程序集将获得新值而无需重新编译。更新只读字段意味着只需要编译第一个程序集,而无需编译任何用户程序集。
示例
using System; class Program{ static void Main(){ Console.WriteLine(Period.HOURS); var person = new Person("John", "Programmer"); person.Print(); } } class Period{ public const int HOURS = 12; public const int MINUTES = 60; } class Person{ private readonly string _title; private readonly string _skill; public Person(string title, string skill){ _title = title; _skill = skill; } public void Change(string skill){ // Error: A readonly field cannot be assigned to // this._skill = skill; } public void Print(){ Console.WriteLine($"{_title}: {_skill}"); } }
输出
12 John: Programmer