使用初始化程序通过枚举循环会产生意外结果

Wim*_*ets 2 c# enums literals

我创建的枚举看起来像这样:

enum MonthOfTheYear : byte
{
    January,
    February,
    March,
    April,
    May,
    June,
    July = 0,
    August,
    September,
    October,
    November,
    December
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,7月初始值为0.这有一些有趣的(侧面)效果:似乎是整数值的"配对".2月和8月现在的值为1,3月和9月有2等:

MonthOfTheYear theMonth = MonthOfTheYear.February;
Console.WriteLine(theMonth + " has integer value of " + (int)theMonth);
Run Code Online (Sandbox Code Playgroud)

MonthOfTheYear theMonth = MonthOfTheYear.August;
Console.WriteLine(theMonth + " has integer value of " + (int)theMonth);
Run Code Online (Sandbox Code Playgroud)

清楚地表明这一点 到目前为止,我觉得很奇怪,我愿意继续. 编辑:我得到指定7月0日使指数重新开始.我不明白为什么他们可以在同一个枚举中共存.

但!如果我然后遍历枚举并输出所有基础整数值,则会出现奇怪现象.

MonthOfTheYear theMonth = MonthOfTheYear.January;

for (int i = 0; i < 12; i++)
{
    Console.WriteLine(theMonth + " has integer value of " + (int)theMonth++);
}
Run Code Online (Sandbox Code Playgroud)

输出

July has integer value of 0
February has integer value of 1
September has integer value of 2
April has integer value of 3
May has integer value of 4
June has integer value of 5
6 has integer value of 6
7 has integer value of 7
8 has integer value of 8
9 has integer value of 9
10 has integer value of 10
11 has integer value of 11
Run Code Online (Sandbox Code Playgroud)

我希望有人可以向我解释幕后发生了什么,因为整数值是连续的,所以我认为这是按预期输出但我还没有看到它.

Raw*_*ing 5

首先,当你在枚举的定义中指定一个值时,后续值从那里开始连续 - 即使你指定了0某个地方,第一个值也将从中开始编号0.因此,您的基本byte价值是:

enum MonthOfTheYear : byte
{
    January = 0, // not specified, so starts at 0
    February = 1,
    March = 2,
    April = 3,
    May = 4,
    June = 5,
    July = 0, // specified, so starts numbering from 0 again
    August = 1,
    September = 2,
    October = 3,
    November = 4,
    December = 5
}
Run Code Online (Sandbox Code Playgroud)

当你使用枚举值递增时++,它只会增加底层值byte- 它不会查看定义enum并转到下一行的元素!

如果这byte没有相应的已定义条目,那么这并不意味着它完全无效 - 只是当你将枚举值转换为字符串时,你得到的byte值是一个字符串.

如果byte几个相应的定义条目...实际上,我不确定将它转换为字符串的确切条目会给你,但它显然不一定是第一个.

基本上MonthOfTheYear.February == MonthOfTheYear.August所以无论你是在调用ToString它还是只是在调试器中查看它,都无法保证不会为另一个调用它.