Edit: Comments at bottom. Also, this.
Here\'s what\'s kind of confusing me. My understanding is that if I have an enum like this...
What I'm noting here is from page 38 of ECMA-335 (I suggest you download it just to have it):
The CTS supports an enum (also known as an enumeration type), an alternate name for an existing type. For the purposes of matching signatures, an enum shall not be the same as the underlying type. Instances of an enum, however, shall be assignable-to the underlying type, and vice versa. That is, no cast (see §8.3.3) or coercion (see §8.3.2) is required to convert from the enum to the underlying type, nor are they required from the underlying type to the enum. An enum is considerably more restricted than a true type, as follows:
The underlying type shall be a built-in integer type. Enums shall derive from System.Enum, hence they are value types. Like all value types, they shall be sealed (see §8.9.9).
enum Foo { Bar = 1 }
Foo x = Foo.Bar;
This statement will be false because of the second sentence:
x is int
They are the same (an alias), but their signature is not the same. Converting to and from an int
isn't a cast.
From page 46:
underlying types – in the CTS enumerations are alternate names for existing types (§8.5.2), termed their underlying type. Except for signature matching (§8.5.2) enumerations are treated as their underlying type. This subset is the set of storage types with the enumerations removed.
Go back to my Foo enum earlier. This statement will work:
Foo x = (Foo)5;
If you inspect the generated IL code of my Main method in Reflector:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
.maxstack 1
.locals init (
[0] valuetype ConsoleTesting.Foo x)
L_0000: nop
L_0001: ldc.i4.5
L_0002: stloc.0
L_0003: call string [mscorlib]System.Console::ReadLine()
L_0008: pop
L_0009: ret
}
Note there's no cast. ldc
is found on page 86. It loads a constant. i4
is found on page 151, indicating the type is a 32-bit integer. There isn't a cast!