[C#] readonly vs const
C#中的readonly和const两个关键字都可以用来定义系统变量,那两者之间有什么区别呢?
1. const变量赋值后,就不可以对其进行修改。且在定义时就需要给它赋值,使用const修饰的变量是static的。可以使用YourClass.ConstantName的方式进行访问;
2. readonly变量可以在定义时赋值,也可以在构造方法中赋值或者修改定义时赋给的初始值;
另外还有一个细微的差别。看下面的场景,我在AssemblyA中定义了一个类如下:
public class Readonly_VS_Const { public const int I_Const_Value = 100; public readonly int I_Readonly_Value = 20; public Readonly_VS_Const() { I_Readonly_Value = 55; } }
在AssemblyB中引用了AssemblyA,并且使用了这些常量,
static void Main(string[] args) { int constValue = Readonly_VS_Const.I_Const_Value; Readonly_VS_Const vs = new Readonly_VS_Const(); int readonlyValue = vs.I_Readonly_Value; Console.WriteLine("Const Value:{0}--Readonly Value:{1}", constValue, readonlyValue); Console.ReadKey(); }
查看一下IL代码,
注意查看使用黄色和绿色框标记的两行代码。
假设AssemblyA和AssemblyB编译完成后均放在AssemblyB的目录下
1. const变量类似与一种替换的方式,直接将定义的100写入到IL代码中。当我修改了I_Const_Value的值为200后,AssemblyB需要在程序重新编译后才能获得更新后的数值;
2. readonly的变量值,很像ref类型,readonly值不会直接写入到AssemblyB的IL代码中,这就意味者如果AssemblyA中readonly的值被修改后,你只需要重新编译一下AssemblyA即可。AssemblyB在调用时会找到根据变量的内存位置读取修改后的值。
static readonly vs const,
onst和static readonly的确很像:通过类名而不是对象名进行访问,在程序中只读等等。在多数情况下可以混用。
二者本质的区别在于,const的值是在编译期间确定的,因此只能在声明时通过常量表达式指定其值。而static readonly是在运行时计算出其值的,所以还可以通过静态构造函数来赋值。
请看下面的例子:
class Program { static readonly int A = B * 10; static readonly int B = 10; static void Main(string[] args) { Console.WriteLine("A: {0} B: {1}", A, B); } }
结果如下:
将static readonly修改为const,
class Program { const int A = B * 10; const int B = 10; static void Main(string[] args) { Console.WriteLine("A: {0} B: {1}", A, B); } }
结果如下:
那么为什么是这样的呢?const是静态常量,所以在编译的时候就将A与B的值确定下来了(即B变量时10,而A=B*10=10*10=100),那么Main函数中的输出当然是A is 100,B is 10啦。而static readonly则是动态常量,变量的值在编译期间不予以解析,所以开始都是默认值,像A与B都是int类型,故都是0。而在程序执行到A=B*10;所以A=0*10=0,程序接着执行到B=10这句时候,才会真正的B的初值10赋给B。
感谢您的阅读!