日期:2014-05-17 浏览次数:20836 次
我们都知道,使用const关键字可以将字段或局部变量声明为常量,其不能被修改。
readonly关键字被用来声明只读字段,主要用于字段。
两者有一定的相似性,但是也有明显的差异性,所以本文将两者结合在一起来进行说明。
一开始,我们先给出四个代码小片段,这些代码小片段的功能都是使用const关键字来定义常量,但是其中某些小片段的做法是不正确的,希望大家能够找出来。
Code1:
private const int FIRST_NUM = 1;
Code2:
private static const int SECOND_NUM = 1;
Code3:
int t = 1; private const int THIRD_NUM = t + 1;
Code4:
private const int FIFTH_NUM = FIRST_NUM + 1;
大家知道哪些代码片段有问题吗?
答案是,代码片段2及代码片段3的做法存在错误。
为什么呢?(小沈阳唱着说:为什么呢?)
Code2不正确的原因是:
const 默认就是静态的,所以在声明中显式地加上static 关键字的做法明显是错误的。这一点,可以通过查看IL代码来证明,其中Code1对应的IL代码如下:
.field private static literal int32 FIRST_NUM = int32(0x00000001)
很显然,常量FIRST_NUM 默认就是静态的(static )。
那么,readonly字段能不能被设置成静态呢?
做个实验就知道了,代码如下:
private static readonly int firstnum = 1;
编译无错,正常。
到这里,可以得出readonly及const的第一个区别:const 默认就是静态的,而 readonly 如果设置成静态的就必须显示声明(区别1)。
Code3不正确的原因是:
const 字段只能在该字段的声明中初始化。不能从一个变量中提取值来初始化常量。这里面更深层次的原因就是:const 字段是编译时常数。在编译时就应该确定其具体值。
那么,readonly字段能不能使用变量来进行初始化呢?
同样使用实验来验证我们的想法,代码如下:
public class ReadOnlyAndConstClass { private readonly int secondnum; public ReadOnlyAndConstClass() { int t = 1; secondnum =t +1; } }
很显然,是可以的,但必须在构造函数中。
这是因为 readonly 是在计算时执行的,当然它可以用某些变量来进行初始化。
到这里,总结出readonly及const的第二个区别:
const 字段是编译时常数,而 readonly 字段可用于运行时常数(区别2)。
当然,我们还能得出另外一个不同点:
const 字段只能在该字段的声明中初始化。readonly 字段可以在声明或