const 还是 static readonly

到底是 const 还是 static readonly

 

真的一样?

const 和 static readonly 常在程序中用来声明常量,调用方法也没有什么不同,他们真的一样吗?我们可以做个试验。

程序集内的常量

现在我们建立一个程序,里面有一个MyClass的类,分别用const和static readonly定义常量

clip_image001

然后在程序运行时输出

clip_image002

运行程序,输出

clip_image003

把这两个值改一下,再运行

clip_image004

clip_image005

看来没什么问题

跨程序集的常量

现在我们建新建一个类库,创建一个类,同样的内容

clip_image006

在程序中加入对类库的引用,并把这两个常量输出

clip_image007

正常输出

clip_image008

改变这两个值

clip_image009

我们现在Rebuild那个类库(在类库上右键->Rebuild,不要Rebuild程序)

clip_image010

这样做是为了模拟在程序只对有更改的模块进行更新的情境,Rebuild好后,找到程序的生成目录,把新的DLL放进去,替换掉旧的,启动程序。

clip_image011

问题已经出来了,这样的结果不是我们想要的。

一切尽在IL

我们用ildasm打开exe看一下他的Main方法

clip_image012

我们可以看到,用const定义的常量在编译时是直接把值copy过来的,IL中就像对待字面量一样处理(是不是有点像C/C++的宏展开和内联?)而用static readonly定义的“常量”,在IL中就是一个加载成员变量的操作。

到底是 const 还是 static readonly

用const声明的常量,值在编译时计算,然后直接把常量的值嵌入到IL代码中,不会有栈操作,性能很高,也正因为这一点,const后面只能跟常量表达式,而且在跨程序集引用时,如果改变常量的值,则整个程序需要重新编译,看来const不是可以随便乱用的,如果某个值在以后的版本中可能会改变,那就不要用const,避免不必要的麻烦。

用static readonly 声明的并不能叫做常量,应该叫做只读变量,原因是它的值是在运行时进行计算的,因此具有很大的灵活性,它后面不仅仅可以跟常量表达式,还可以跟一个值只有在运行进才能确定的表达式,比如获取系统版本:

clip_image013

如果你追求性能,如果你足够谨慎,请用const,如果你想要灵活,想要安全,请用static readonly。

原文地址:https://www.cnblogs.com/Leo_wl/p/3452968.html