const和readonly都是给字段设置常量。何谓常量,是指在程序中直接给出其值,在整个操作过程中其值保持不变的数据。
const关键字是静态常量,在编译时就初始化好,对于每一次编译后的结果,const的值是固定的,它指定的全局变量或局部变量的值不能被修改。
而readonly的值是可以在运行的时候才确定值的~~.
使用场景
1、const定义常量后,是一个固定的硬编码值,不允许再次修改,而readonly允许在类的构造函数中进行再次赋值
2、在不同类实例中有不同的实例变量,实例变量可以采用readonly
Static Readonly
const 是编译时常量,readonly 是运行时常量,const 较高效,readonly更灵活,在应用上一般都以 static readonly 来代替const,以平衡const在灵活性上的不足,所以static readonly等效于const。
static readonly允许在类的静态构造函数中进行赋值
Const比ReadOnly效率高
因为const变量经过编译器编译后,我们在代码中引用const变量的地方会用const变量所对应的实际值来代替
const int value = 1000;
Console.WriteLine(value);
和下面代码所生成代码的IL是一致的
Console.WriteLine(1000);
Readonly比Const灵活
字段声明为const,则它不是一个变量,而是一个笃定的硬编码值 ,它是隐式static的
readOnly允许把一个字段设置为常量,但也可以执行一些运算,以确定她的初始值。可以在构造函数中给readonly字段赋值,但不能在其它地方。它还可以是个实例变量而不static的,每个类都有不同的值 ,和const不同,要定义为static,必须显式的声明
class Program
{
static readonly int readValue = 2000;
static Program()
{
readValue = 55; //只能在构造函数上下文中给它赋值
}
static void Main(string[] args)
{
Console.WriteLine(readValue);
}
}
readonly变量是运行时变量,其赋值行为发生在运行时。readonly的全部意义在于,它在运行时第一次被赋值后将不可以改变。当然,“不可以改变”分为两层意思:
1)对于值类型变量,值本身不可改变(readonly,只读)。
2)对于引用类型变量,引用本身(相当于指针)不可改变。
首先我们来看值类型变量,如下代码:
public class Sample
{
public readonly int readValue;
public Sample(int value)
{
readValue = value;
}
}
Sample的实例readValue在构造方法中被赋值后就不可以改变,下面的代码将不会编译通过
Sample sample = new Sample(100);
//sample.intValue = 18; //无法对只读的字段赋值(构造函数或变量初始值指定项中除外)
Console.WriteLine(sample.readValue);
readonly所代表的运行时含义有一个重要的作用,就是可以为每个类的实例指定一个readonly的变量。以Sample这个类为例,可以在运行时生成多个实例,而同时,又可以为每个实例生成自己的readonly变量,如下:
Sample sample = new Sample(100);
Sample sample = new Sample(200);
Sample sample = new Sample(300);
针对引用类型变量,如下代码
public readonly Student student;
public Sample(Student value)
{
student = value;
}
Sample的ReadOnlyValue是一个引用类型变量,赋值后,变量不能再指向任何其他的Student实例,所以,下面的代码将不会编译通过:
Sample sample = new Sample(new Student() { Id = 1, name = "张小三" });
//sample.student = new Student() { Id = 2, name = "张小四" }; //无法对只读的字段赋值(构造函数或变量初始值指定项中除外)
Console.WriteLine(sample.student.name);
但是,我们之前已经提到过了,引用本身不可改变,引用所指的实例的值,却是可以改变的,下面的代码将会被允许:
Sample sample = new Sample(new Student() { Id = 1, name = "张小三" });
sample.student.name = "张小四";
Console.WriteLine(sample.student.name);
const和readonly区别:
题外话:静态构造函数和普通构造函数哪个先执行?
class Sample
{
public Sample()
{
Console.WriteLine("普通构造函数");
}
static Sample()
{
Console.WriteLine("静态构造函数");
}
}
输出打印结果:
普通构造函数
静态构造函数