我知道Enums被编译为常量,因此更改它们会导致重大变化。我想知道的是,为什么Enums的编译方式与静态只读变量相同?
答案 0 :(得分:9)
两个给出的答案在技术上都是正确的,但是错过了使用静力学(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
}
在编译时,编译器将对常量的所有引用替换为该常量的实际值。它能够这样做,因为必须在编译时预定义常量。这与静态只读值不同,静态readonly值虽然是静态的,但实际上是在运行时解析的。请看以下示例:
static readonly Encoding = Encoding.GetEncoding("GB2132");
编译器无法知道GB2132是否实际存在于要运行此代码的计算机上。解决此值的唯一方法是在运行时。 Static确保值本身不绑定到实例的生命周期,并且readonly确保该值只能设置一次。编译器无法在编译时替换对该字段的引用,因为该值根本无法知道。
逻辑上,只有原始类型可以标记为常量。
现在,对于枚举,它非常简单。枚举只不过是带有标签的整数值。所以下面的代码:
enum MyEnum
{
First,
Second,
Third
}
static void Main()
{
MyEnum test = MyEnum.First;
if (test == MyEnum.Second)
{
// whatever
}
}
将由编译器解决:
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
}
}
这反过来意味着对常量字段的实际引用可以用编译时已知的值替换,使得代码的最终版本类似于:
static void Main()
{
int test = 0;
if (test == 1 )
{
// whatever
}
}
答案 1 :(得分:7)
它们可以比字段更有效,因此当它们可以直接嵌入到IL中时,不需要以相同的方式编译它们。
[枚举]加载相同 加载const值的方式。它们直接嵌入到 IL。另一方面,字段需要字段加载指令 (ldsfld)会对性能产生一定影响。因此,枚举 与典型用法中的const一样快;字段有点慢。
(Source)
答案 2 :(得分:1)