zoukankan      html  css  js  c++  java
  • [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。

    感谢您的阅读!

  • 相关阅读:
    以 DirectUI 方式实现的ImageButton
    文件夹操作:复制和删除整个文件夹
    继承CListCtrl,然后重载OnLButtonUP消息,发现变成双击才触发???
    CListCtrl获取列数
    获取单个字符尺寸和字符串尺寸
    谈谈CListCtrl如何调整行高
    得到鼠标的屏幕坐标
    CListCtrl控件中显示进度条
    #pragma pack(push,1) 与 #pragma pack(1)的区别
    #pragma pack
  • 原文地址:https://www.cnblogs.com/yang-fei/p/7401854.html
Copyright © 2011-2022 走看看