[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。

感谢您的阅读!

posted @ 2017-08-20 22:44  Yang-Fei  阅读(1911)  评论(0编辑  收藏  举报