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...
Why not... it is perfectly valid, for example, for a structure to hold an int internally, and be convertible to int with an explicit cast operator... lets simulate an Enum:
interface IEnum { }
struct MyEnumS : IEnum
{
private int inner;
public static explicit operator int(MyEnumS val)
{
return val.inner;
}
public static explicit operator MyEnumS(int val)
{
MyEnumS result;
result.inner = val;
return result;
}
public static readonly MyEnumS EnumItem1 = (MyEnumS)0;
public static readonly MyEnumS EnumItem2 = (MyEnumS)2;
public static readonly MyEnumS EnumItem3 = (MyEnumS)10;
public override string ToString()
{
return inner == 0 ? "EnumItem1" :
inner == 2 ? "EnumItem2" :
inner == 10 ? "EnumItem3" :
inner.ToString();
}
}
This struct can be used quite the same way a struct can... of course, if you try to reflect the type, and call IsEnum property it will return false.
Let's look at some usage comparison, with the equivalent enum:
enum MyEnum
{
EnumItem1 = 0,
EnumItem2 = 2,
EnumItem3 = 10,
}
Comparing usages:
Struct version:
var val = MyEnum.EnumItem1;
val = (MyEnum)50;
val = 0;
object obj = val;
bool isE = obj is MyEnum;
Enum en = val;
Enum version:
var valS = MyEnumS.EnumItem1;
valS = (MyEnumS)50;
//valS = 0; // cannot simulate this
object objS = valS;
bool isS = objS is MyEnumS;
IEnum enS = valS;
Some operations cannot be simulated, but this all shows what I intended to say... Enums are special, yes... how much special? not that much! =)
A Enum
's underlying type is the type used to store the value of the constants. In your example, even though you haven't explicitly defined the values, C# does this:
enum Animal : int
{
Dog = 0,
Cat = 1
}
Internally, Animal
is made up of two constants with the integer values 0 and 1. That's why you can explicitly cast an integer to an Animal
and an Animal
to an integer. If you pass Animal.Dog
to a parameter that accepts an Animal
, what you are really doing is passing the 32bit integer value of Animal.Dog
(in this case, 0). If you give Animal
a new underlying type, then the values are stored as that type.