Q: In C #, how do we express enumeration types?
A: You can use the enum keyword (keyword) to declare an enum type (enum type):
- //Code #01
- Public enum Alignment
- {
- Left,
- Center,
- Right
- }
--------------------------------------------------------------------------------
q:c# enum type is a value type (value of type) or reference type (reference type)?
A: Enum types are value types.
--------------------------------------------------------------------------------
Is Q:system.enum an enumeration type?
A: No.
--------------------------------------------------------------------------------
What does Q:system.enum have to do with enum type (enum type)?
A:system.enum is an abstract class, and all enum types inherit directly from it, and of course inherit all of its members.
--------------------------------------------------------------------------------
Q: So System.Enum belongs to the reference type?
A: Yes.
--------------------------------------------------------------------------------
Q: Since System.Enum is a reference type and the enumeration type is directly inherited from System.Enum, why is the enum type not a reference type?
A: This type of inheritance is implicit and is being expanded by the compiler, the code #1的Alignment枚举被展开后的IL代码如下:
- //Code #02
- . class public auto ANSI sealed aligment
- extends [mscorlib]system.enum
- {
- . field public static literal aligment left = Int32 (0x00000000)
- . field public static literal aligment Center = Int32 (0x00000001)
- . field public static literal aligment right = Int32 (0x00000002)
- . field public specialname rtspecialname int32 value__
- }
From the declaration, you can see that aligment is indeed inherited from System.Enum, but you cannot explicitly declare such an inheritance in C #.
--------------------------------------------------------------------------------
Q: But you don't seem to answer why the enum type inherits from a reference type, but still a value type!
A: You know, All value types are descendants of System.ValueType, enum types are no exception, enum types are directly inherited from System.Enum, and System.Enum are directly inherited from System.ValueType, so the enumeration type is also System.ValueType Offspring.
--------------------------------------------------------------------------------
Q: Wait! Shouldn't a type derived from System.ValueType be a value type? Why would System.Enum be a reference type?
A: The correct argument is that "value types are descendants of System.ValueType", but System.ValueType descendants are not all value types, System.Enum is the only special case! In all descendants of System.ValueType, all but System.Enum are value types. In fact, we can be in. NET source code, find the System.Enum declaration:
- Public Abstract class Enum:valuetype, IComparable, IFormattable, IConvertible
Please note that the Enum declaration in the. NET Framework SDK v2.0.3600.0 documentation is wrong:
Public abstract struct enum:icomparable, IFormattable, iconvertible
--------------------------------------------------------------------------------
Q: What kind of relationship does the C # enumeration type, System.Enum, System.ValueType, value types, and reference types have when they start to get dizzy?
A: To put it simply,
1. All enum types (enum type) are value types.
2. System.Enum and System.ValueType are reference types themselves.
3. The enumeration type (enum type) is implicitly inherited directly from System.Enum, and the inheritance can only be expanded automatically by the compiler. However, System.Enum itself is not an enumeration type (enum type).
4. System.Enum is a special case that inherits directly from the System.ValueType (see Code #03) but is itself a reference type.
OK, now look at the code below, can you guess the output of it?
- // code #04
- static void main ()
- {
- type t = typeof (System.Enum);
-
- if (t. Isenum)
- console.writeline ( Span class= "string" > "I ' M enum type.");
-
- if (t. Isvaluetype)
- console.writeline ( "I ' M value type.");
-
Don't be surprised at the results of the program running without any output! For the first judgment, we know that System.Enum is not an enumeration type. But what about a second judgment? System.Enum obviously inherit from the System.ValueType, but do not recognize the descendants of System.ValueType! This is. NET A special case, just reflects the System.Enum is the particularity.
--------------------------------------------------------------------------------
Q: Since the enumeration type is a value type, it naturally involves the problem of boxing and unpacking (boxing and unboxing), so what will the enumeration type be boxed into? [Updated]
A: Enumeration types can be boxed into System.Enum, System.ValueType, System.Object, or system.iconvertible, system.iformattable, System.IComparable.
Note: on. NET 1.1, enumeration types can only be boxed to System.Enum, System.ValueType, System.Object, and on. NET 2.0, Enumeration types can also be boxed into the three interfaces implemented by System.Enum: System.iconvertible, System.IComparable, system.iformattable. The corresponding boxing operation can be either implicit or explicit.
The following C # code:
- //Code #05
- See Code #01 for Alignment.
- static void Main ()
- {
- Alignment a = Alignment.center;
- Console.WriteLine (A.tostring ());
- Console.WriteLine (a);
- }
The corresponding IL code is:
- //Code #06
- . method Private hidebysig static void Main () cil managed
- {
- . entrypoint
- //Code size:32 byte (s)
- . maxstack 1
- . Locals (
- Enumerationfaq.alignment alignment1)
- l_0000:ldc.i4.1
- l_0001:stloc.0
- l_0002:ldloc.0
- L_0003:box enumerationfaq.alignment
- L_0008:call instance string [Mscorlib]system.enum::tostring ()
- L_000d:call void [Mscorlib]system.console::writeline (string)
- L_0012:nop
- l_0013:ldloc.0
- L_0014:box enumerationfaq.alignment
- L_0019:call void [Mscorlib]system.console::writeline (object)
- L_001e:nop
- L_001f:ret
- }
From the IL code we can see that the enumeration type is boxed two times. The first time (l_0003) is boxed into System.Enum, and the second (l_0014) is boxed into System.Object.
But if you let the compiler choose the boxed type for you automatically, it will take precedence over System.Enum:
- //Code #07
- See Code #01 for Alignment.
- Class Program
- {
- static void Main ()
- {
- Alignment a = Alignment.center;
- Print (a);
- }
- static void Print (iconvertible c)
- {
- Console.WriteLine (c);
- }
- static void Print (IFormattable f)
- {
- Console.WriteLine (f);
- }
- static void Print (IComparable c)
- {
- Console.WriteLine (c);
- }
- static void Print (Object o)
- {
- Console.WriteLine (o);
- }
- static void Print (ValueType v)
- {
- Console.WriteLine (v);
- }
- static void Print (Enum e)
- {
- Console.WriteLine (e);
- }
- }
The above code will be compiled into the following IL:
- //Code #08
- . method Private hidebysig static void Main (string[] args) cil managed
- {
- . entrypoint
- //Code size:15 byte (s)
- . maxstack 1
- . Locals (
- Enumerationfaq.alignment alignment1)
- l_0000:ldc.i4.1
- l_0001:stloc.0
- l_0002:ldloc.0
- L_0003:box enumerationfaq.alignment
- //Call static void Print (Enum e);
- L_0008:call void Enumerationfaq.program::P rint ([mscorlib]system.enum)
- L_000d:nop
- L_000e:ret
- }
Questions and Answers about C # enumerations: Basics