《Effective C#》读书笔记(2)
Item 2: Prefer readonly to const
第2项: 定义常量时,优先使用readonly,而不是const
在C#中存在两种定义常量的方法。第一种是编译时(compile-time)的常量,一种是运行时(Runtime)的常量。
编译时常量:public const int year= 2005;(使用const关键字)
运行时常量:public static readonly int year= 2005;(使用readonly关键字)
让我们先来看看这两种常量的区别:
1、编译时常量的值永远不会改变;运行时常量可能具有不同的值。
2、编译时常量只能在该字段的声明中初始化;运行时常量可以在声明或构造函数中初始化。
3、编译时常量比运行时常量速度稍微快点,但是灵活性远远比不上运行时常量。
4、编译时常量可以用来修饰函数内部常量和字段的常量,而运行时常量只能修饰字段常量。
为什么要优先使用运行时常量呢?
首先它能够定义更多的类型。编译时常量只能定义字符串和数值,而运行时常量的赋值在Runtime进行时,这样使它具有更多的灵活行,这样运行时常量的值就可以任何类型,但是你必须在构造器或初始化时给它赋值。同时运行时常量支持new来赋值:
private static readonly DateTime time= new DateTime( 2000, 1, 1, 0, 0, 0 );
其次运行时常量可能具有不同的值,而编译时常量的值是唯一的。编译时常量是在编译时赋值的,要想改变它的值必须再次编译1次;而运行时常量是在运行时解析的,你可以在不需要再次编译的情况下改变它的值,这样就大大的增加了可维护性。可以看出编译时的常量只是值的替换,是硬代码;而运行时常量只是在runtime才被解析,并不是一个值,是动态载入的。
让我们看看以下的例子体会下运行时常量的优势:
public class A
{
public const int a=18;
public static readonly int b=20;
}
这时你在另一个类中(另一个assembly中)引用A类的两个常量:
Console.WriteLine( "Value is {0},{1}", A.a,A.b );
得到的结果是:Value is 18,20
当我们修改A类为以下:
public class A
{
public const int a=19;
public static readonly int b=21;
}
再次调用,你肯定会认为得到的结果是:Value is 19,21
实际上得到值是18,21。因为没有编译,编译时常量a的值并没有变化。
总之,只有当你必须要在编译时确定值的情况下,才使用const。记住,这些值是永远不变的。其他一切情况下,使用readonly来 最大的提高灵活性。