我在C#中练习枚举,我无法理解这些
的输出void Main()
{
MyEnum a = MyEnum.Top;
Console.WriteLine(a);
}
对于此测试,我的枚举和输出是
enum MyEnum
{
Left, Right, Top, Bottom // Top
}
enum MyEnum
{
Left, Right, Top = 0, Bottom // Left
}
我认为在朗姆酒时间程序中选择值为0的第一项,以确认我将值0分配给底部
enum MyEnum
{
Left, Right, Top = 0, Bottom = 0 // Bottom
}
然后我想也许程序选择值为0的第一项,但按字母顺序搜索 所以我将 顶部更改为 ATop 并更改了测试用例
void Main()
{
MyEnum a = MyEnum.ATop;
Console.WriteLine(a);
}
enum MyEnum
{
Left, Right, ATop = 0, Bottom = 0 // Bottom
}
enum MyEnum
{
Left, Right, ATop = 0, Bottom // Left
}
我知道没有人以这种方式使用枚举,但我想知道Enum的这种特殊行为。
答案 0 :(得分:7)
好像你已经发现编译器默认开始计数为零。
enum MyEnum
{
Left, Right, Top = 0, Bottom = 0 // Bottom
}
转换为此
.class nested private auto ansi sealed MyEnum
extends [mscorlib]System.Enum
{
.field public specialname rtspecialname int32 value__
.field public static literal valuetype X/MyEnum Left = int32(0)
.field public static literal valuetype X/MyEnum Right = int32(1)
.field public static literal valuetype X/MyEnum Top = int32(0)
.field public static literal valuetype X/MyEnum Bottom = int32(0)
}
运行时实际上大部分时间都与底层类型一起使用。所以有趣的是,这就是
static void Main()
{
MyEnum a = MyEnum.Top;
Console.WriteLine(a);
Console.ReadKey();
}
甚至不使用实际的枚举成员:
.method private hidebysig static
void Main () cil managed
{
.maxstack 1
.entrypoint
.locals init (
[0] valuetype X/MyEnum a
)
IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: stloc.0
IL_0003: ldloc.0
IL_0004: box X/MyEnum
IL_0009: call void [mscorlib]System.Console::WriteLine(object)
IL_000e: nop
IL_000f: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
IL_0014: pop
IL_0015: ret
}
它只使用值0.决定使用Console.WriteLine
打印的名称从System.Enum.ToString
开始,System.Type.GetEnumName(object)
中的高潮开始。
public virtual string GetEnumName(object value)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
if (!this.IsEnum)
{
throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
}
Type type = value.GetType();
if (!type.IsEnum && !Type.IsIntegerType(type))
{
throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnumBaseTypeOrEnum"), "value");
}
Array enumRawConstantValues = this.GetEnumRawConstantValues();
int num = Type.BinarySearch(enumRawConstantValues, value);
if (num >= 0)
{
string[] enumNames = this.GetEnumNames();
return enumNames[num];
}
return null;
}
正如您所看到的,搜索要打印的名称的实际方法是通过字段名称(通过反射找到)进行二进制搜索。
这只是当前的实现,但可能因不同的编译器和/或运行时版本而有所不同。语言规范不保证上述代码的任何特定顺序或结果。
答案 1 :(得分:-1)
Enum只不过是命名一些常数。
就像我们有一些成果。苹果,香蕉,橙。我们有一个场景,如果一个婴儿1岁,它将获得橙色,如果2将获得香蕉,如果3将获得苹果。那我们怎么写呢?
一个解决方案就像:
int fruiteType = 0;
if(ageOfBaby == 1)
fruiteType == 1;//assuming Orange = 1;
if(ageOfBaby == 2)
fruiteType == 2;//assuming Banana = 2;
if(ageOfBaby == 3)
fruiteType == 3;//assuming Apple = 3;
我们可以巧妙地使用Enum。喜欢:
enum Fruits {Orange, Banana, Apple};
int fruiteType = 0;
if(ageOfBaby == 1)
fruiteType == (int)Fruits.Orange;
if(ageOfBaby == 2)
fruiteType == (int)Fruits.Banana;
if(ageOfBaby == 3)
fruiteType == (int)Fruits.Apple;
默认情况下,您将分别在上述条件下的fruiteType变量中获得0,1,2。如果你想改变默认值,你可以定义如下:
enum Fruits {Orange = 1, Banana, Apple};
为什么这很重要。当我们假设这些值时,我们可能会忘记序列,从而产生麻烦。但是当我们命名它们时,我们永远不会忘记fruitType = 1的哪个值。
由于