两个给出的答案在技术上都是正确的,但是错过了使用静力学(readonly)对差异常数的解释.在C#中,常量总是比readonly快,原因很简单,最好用一个小代码示例表示:
const int MyConstant = 10;
static readonly int MyReadonly = 20;
static void Main()
{
int result = MyConstant + MyReadonly;
// the above statement will be resolved to:
// int result = 10 + MyReadonly
}
Run Code Online (Sandbox Code Playgroud)
在编译时,编译器将对常量的所有引用替换为该常量的实际值.它能够这样做,因为必须在编译时预定义常量.这与静态只读值不同,静态readonly值虽然是静态的,但实际上是在运行时解析的.请看以下示例:
static readonly Encoding = Encoding.GetEncoding("GB2132");
Run Code Online (Sandbox Code Playgroud)
编译器无法知道GB2132是否实际存在于要运行此代码的计算机上.解决此值的唯一方法是在运行时.Static确保值本身不绑定到实例的生命周期,并且readonly确保该值只能设置一次.编译器无法在编译时替换对此字段的引用,因为无法知道该值.
从逻辑上讲,只有原始类型可以标记为常量.
现在在枚举的情况下,它非常简单.枚举只不过是带有标签的整数值.所以下面的代码:
enum MyEnum
{
First,
Second,
Third
}
static void Main()
{
MyEnum test = MyEnum.First;
if (test == MyEnum.Second)
{
// whatever
}
}
Run Code Online (Sandbox Code Playgroud)
将由编译器解决:
const int MyEnum_First = 0;
const int MyEnum_Second = 1;
const int MyEnum_Third = 2;
static void Main()
{
int test = MyEnum_First;
if (test == MyEnum_Second )
{
// whatever
}
}
Run Code Online (Sandbox Code Playgroud)
这反过来意味着对常量字段的实际引用可以用编译时已知的值替换,使得代码的最终版本类似于:
static void Main()
{
int test = 0;
if (test == 1 )
{
// whatever
}
}
Run Code Online (Sandbox Code Playgroud)