解释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值,它就像对内存位置的引用。该值不会嵌入到第二个程序集的中间语言中。这意味着如果更新了内存位置,第二个程序集无需重新编译即可获得新值。更新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

更新于:2021年5月19日

681 次浏览

开启你的职业生涯

完成课程获得认证

开始学习
广告