1.常成员的定义:在声明前就已经能够明确该成员取值,且该成员的值不会在程序运行的过程中发生变化。
2.常成员的初始化和引用:
直接在声明变量的位置初始化
例如:public const <TypeName> <VariantName>=<Value>;
Note:<Value>必须被设置,该值也可以是null
const成员的引用方式为:
<ClassName>.<ConstantName>
3.讨论
与C++不同,在C#中,常量不再归某一个对象所有,而是做为类的通用成员而存在。从引用方式来看,C#中的常量更加类似于static成员。为了验证const成员和static成员之间的关系,我们写一个测试类,并将其反汇编成IL语言,通过对CLR层面的分析寻找相关的线索。
class
A
... {
public static int nsTest = 0;
public const int ncTest = 0;
public void A()
...{
……
}
}
... {
public static int nsTest = 0;
public const int ncTest = 0;
public void A()
...{
……
}
}
上述代码反汇编后,nsTest,ncTest两个变量的IL描述如下:
.field public static int32 nsTest
.field public static literal int32 ncTest = int32(0x00000000)
从IL语句字面上我们可以看出,两个变量果然均被声明为static模式,不同的是ncTest声明语句中有literal关键字,而nsTest却没有。对这个关键字的解释我没有在MSDN上查到,但是根据C++中存储常量和字面常量的知识,我猜测literal关键字的作用是标志该常量为字面常量。简单解释一下两种常量的区别,存储常量依托一个变量,存储在数据存储区,而字面常量则不依托于变量,直接编译到程序中去。ncTest和nsTest虽然都由静态关键字声明,但是nsTest占用数据存储区,而ncTest却直接嵌入到程序中,两种类型的成员虽然有相同的调用方式,但内部运作机制还是有很大的区别的,显然,调用const成员的效率要高于调用static成员。
在编写程序时,对于经常在程序中使用的常量,例如异常中的错误代码,与我们往往习惯性的写成以下形式:
public
static
class
ErrCode
... {
public static int ERR_SUCCESS = 0x00001;
}
... {
public static int ERR_SUCCESS = 0x00001;
}
而上述代码正确的写法我认为应该是:
public
static
class
ErrCode
... {
public const int ERR_SUCCESS = 0x00001;
}
... {
public const int ERR_SUCCESS = 0x00001;
}
以上只是我对const对象的观点和猜测,欢迎老鸟指正