const跟readonly的区别

const和readonly的区别
  1. readonly和const都是用来标识常量的。
  2. 初始化值不同
      const修饰的常量必须在声明的同时赋值。
      readonly字段可以在初始化(声明或构造函数)的过程中赋值。在其它地方不能赋值,否则编译器报错。因此根据所使用的构造函数,readonly字段可能具有不同的值。
      readonly是实例成员,所以不同的实例可以有不同的常量值,这使readonly更灵活。
    1. const字段是编译时常量,而readonly字段可用于运行时常量。
      constf声明的常量,在编译的时候,用计算出的这个确定的值去替换调用该常数的每个地方。如:
        public const int n = 1;
        public const int m = n + 1;//正确
        public const int a;
        public const int b = a + 1;//错误,a是一个变量,显然不能在编译时计算结果
      注意:程序中调用const声明的n,在编译后产生的中间语言代码中,是用1来进行替换的。如果想让n=2,则需要将当前类库重新编译一下,否则调用n的地方还是1。

      readonly允许把一个字段设置成常量,但可以进行一些运算,来确定它的初始化值。因为readonly是在计算时执行的,所以可以用某些变量初始化,在运行时才确定该值。例如:
       
    1. 01
    class Person
    02 {
    03     public readonly uint nowtime = (uint)DateTime.Now.Ticks;
    04 }
    05 class Program
    06 {
    07     static void Main(string[] args)
    08     {
    09         Person p = new Person();
    10         Console.WriteLine(p.nowtime);
    11         Console.ReadKey();
    12     }
    13 }
  1. const默认是静态的,而readonly如果设置成静态的就必须显示声明。
  2. const修饰的值类型是有限制的,object、Array(数组)和struct(结构)不能声明为const常量。readonly可以是任何类型。
      这就是说,当我们需要一个const常量时,若它的类型限制了它不能在编译时被计算出确定的值来,那么我们可以采取将它声明为static readonly的方式来解决。但两者之间有一点细微的差别:由于const字段是编译时常量,而readonly字段可用于运行时常量。所以,如果在一个文件中引用另一个文件中使用const声明的常量,当对该常量的值进行了修改时,则需要重新编译所有和该常量关联的文件;而如果这个常量是使用static readonly声明的,则只需编译初始化该常量的文件却可。
      看看下面的const和static readonly是否可以互换:
      1)static readonly Class1 c1 = new Class1();//不可以换成const。new操作符是要执行构造函数的,所以无法在编译期间确定。const必须在声明的同时赋值。
      2)static readonly Class1 c1 = null;//可以换成const。能够声明为const的引用类型只能为string或值为null的引用类型。
      3)static readonly a = b * 20;
          static readonly b = 10;//可以换成const
      4)static readonly int[] array = new int[] {1,2,3};//不能换成const,道理和1)一样。
      5)void SomeFunction()
          {
              const int a = 10;//不能换成readonly。readonly只能用来修饰类的field,而不能修饰局部变量,也不能修饰property等其它类成员。
          }