C#温故知新(1)---Const和Static Readonly

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wucdsg/article/details/78913622

1.引言

入门两年了,虽不妄自菲薄,但深知还是一枚菜鸟,至于有多菜,也没个评判标准,懵懂无知啊。直到上个月在博客园里面看到了一位网友对于C#基础知识的梳理(这篇文章6年前就存在了),懵逼了,它就像一面镜子一样反射出了我的无知。因此决定从现在开始每隔几天就花半天甚至是一两天的时间梳理一下的C#基础知识,一方面是为了温故知新,一方面是作为后期复习的资料。这个系列会很漫长,文中若有纰漏或者致命的理解错误,敬请留言指责,不必留情,我将感激不尽。

2.Const和Static Readonly的区别

从哪里开始,这是个问题?我看到的那个系列的文章是从“值类型和引用类型”开始的,然后一步步深入,但我决定还是不遵循他的套路吧,虽然他的套路很合理,从一对概念入手:Const和Readonly,都表示常量哦。废话不多说,先看看下面的简单例子:
这里写图片描述

    public class ReadonlyClass
    {
        public static readonly string NAME = "Trump";
        public static readonly string GREETING = "Hello,motherFucker!";
    }
    public class ConstClass
    {
        public const string NAME = "Trump";
        public const string GREETING = "Hello,motherFucker!";
    }
        static void Main(string[] args)
        {
            Console.WriteLine("-----------const-----------");
            Console.WriteLine(ConstClass.NAME);
            Console.WriteLine(ConstClass.GREETING);
            Console.WriteLine("-----------readonly-----------");
            Console.WriteLine(ReadonlyClass.NAME);
            Console.WriteLine(ReadonlyClass.GREETING);
            Console.ReadKey();
        }

这里写图片描述

从结果上看,单纯的就这个简单的例子,似乎是没有区别哦。这样的话,不妨来看看编译之后的代码:

这里写图片描述

这里写图片描述

这里给出的解释是C#语言中两种不同的常量类型:静态常量(compile-time constants)和动态常量(runtime constants),静态常量是指编译器在编译时候会对常量进行解析,并将常量的值替换成初始化的那个值,const就是静态常量;而动态常量的值则是在运行的那一刻才获得的,编译器编译期间将其标示为只读常量,而不用常量的值代替,这样动态常量不必在声明的时候就初始化,而可以延迟到构造函数中初始化,static readonly是动态常量。因此上面第一张图中,const常量编译之后,全部被常量值替换了,而static readonly并没有替换,要等到运行的时候。下面对这对概念就一些细节的区别作出比对:

(1)能否static修饰,上面的第二张图中const常量编译后的IL中间语言明显可以看出它已经是static的,因此const不能使用static重复修饰,这也是为什么把const和static readonly比较而不是readonly

(2)鉴于const是编译时常量,因此只能声明简单的数据类型(int、浮点、枚举、字符串等),假想一下,如果const可以声明自定义类类型,请问编译的时候他将拿什么去替换啊?那时候类型对象内存空间都还没有开辟不是吗?而static readonly不存在这样的问题,它可以修饰任意类型,即是动态常量可以修饰任意数据类型。

(3)在哪儿声明?const常量可以声明在类中也可以在函数体内,但是static readonly常量只能声明在类中,这一点是为什么?没有想清楚,有知道的大神可以留言指点哦

(4)声明时是否一定初始化?const要在声明时必需初始化(否则编译不通过),而static readonly在声明时可以不初始化,可以把初始化延迟到无参静态构造函数中,注意是无参数的静态构造函数哦,这里不贴代码了,你可以自己试试。

扫描二维码关注公众号,回复: 5863749 查看本文章

至此我对于const和static readonly的总结告一段落,一对小小的概念迁出这些,可能是我啰嗦吧,只是想说明白,路漫漫兮其修远啊。

3.问题?

问题一:A?B?
class P
{
    static readonly int A=B*10;
    static readonly int B=10;   
    public static void Main(string[] args)
    {
        Console.WriteLine("A is {0},B is {1} ",A,B);
    }
}
问题2:A?B?
class P
{
    const int A=B*10;
    const int B=10;   
    public static void Main(string[] args)
    {
        Console.WriteLine("A is {0},B is {1} ",A,B);
    }
}

这个问题在网上到处都是,因此没有贴出来源。问题一中的结果是A:0,B:10,不是运行时替换吗?那A应该是100啊怎么会是0啊,注意代码自上而下执行,当执行到:static readonly int A=B*10;这里的B=10还没有执行到啊,因此取默认值0,所有结果是0,而使用const的时候在编译的时候值已经全部确定下来了,到原型的时候并没有static readonly那样的阻碍,因此是你想要的结果A:100,B:10,说一千道一万,一个是编译时常量,一个是运行时常量,任何问题,从这一点出发去思考总是万变不离其宗的。

猜你喜欢

转载自blog.csdn.net/wucdsg/article/details/78913622