Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why were Enums compiled as constants instead of static values?

Tags:

c#

enums

I understand that Enums are compiled as constants, so changing them results in a breaking change. What I'm wondering is why weren't Enums compiled the same way static readonly variables are instead?

like image 619
myermian Avatar asked Dec 30 '11 04:12

myermian


3 Answers

Both given answers are technically correct but miss the explanation for differantiating constants with statics (readonly). In C#, constants are always faster than readonly and the reason is very simple and best expressed with a small code example:

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
}

At compile time, the compiler replaces all references to a constant with the actual value of that constant. It is able to do so because a constant must be predefined at compile time. This differs from static readonly values which although static, are actually resolved at runtime. Take the following example:

static readonly Encoding = Encoding.GetEncoding("GB2132");

There is no way for the compiler to know if GB2132 actually exists on the machine on which this code is intended to run. The only way to resolve this value is at runtime. Static ensures that the value itself is not bound to the lifetime of an instance and readonly ensures that the value can only be set once. There is no way for the compiler to replace references to this field at compile time since the value simply can't be known.

Logically, only primitive types can be marked as constant.

Now in case of enums, it's very simple. Enums are nothing more than integer value's with a label. So the following code:

enum MyEnum
{   
    First,
    Second,
    Third
}

static void Main()
{
    MyEnum test = MyEnum.First;

    if (test == MyEnum.Second)
    {
      // whatever
    }
}

Will be resolved by the compiler to:

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
    }
}

Which in turns means the actual references to constant fields can be replaced with the value known at compile time, making the final version of the code something like:

static void Main()
{
    int test = 0;

    if (test == 1 )
    {
      // whatever
    }
}
like image 63
Polity Avatar answered Sep 30 '22 12:09

Polity


They can be more efficient than fields, so there's no need to compile them in the same way when they can be directly embedded into the IL.

[Enums] are loaded in the same way that const value are loaded. They are embedded directly into the IL. Fields, on the other hand, require a field load instruction (ldsfld) which will impact performance somewhat. Enums are therefore just as fast as const in typical usage; fields are somewhat slower.

(Source)

like image 30
keyboardP Avatar answered Sep 30 '22 12:09

keyboardP


From enum (C# Reference)

Just as with any constant, all references to the individual values of an enum are converted to numeric literals at compile time

So am I missing something?

like image 26
Adriaan Stander Avatar answered Sep 30 '22 13:09

Adriaan Stander