C# 中的枚举






4.75/5 (97投票s)
2007年5月15日
6分钟阅读

348457
C# 枚举教程
引言
让我们来学习 C# 中的枚举。但在此之前,让我们先了解使用枚举的必要性。请看下面的程序。
P1.cs
class Demo
{
public static void Main()
{
int Sunday = 0;
System.Console.WriteLine(Sunday);
}
}
输出
0
上面的程序编译并成功运行,得到所需的输出。让我们添加其他工作日。
P2.cs
class Demo
{
public static void Main()
{
int Sunday = 0;
int Monday = 1;
int Tuesday = 2;
int Wednesday = 3;
int Thursday = 4;
int Friday = 5;
int Saturday = 6;
System.Console.WriteLine(Sunday);
System.Console.WriteLine(Monday);
System.Console.WriteLine(Tuesday);
System.Console.WriteLine(Wednesday);
System.Console.WriteLine(Thursday);
System.Console.WriteLine(Friday);
System.Console.WriteLine(Saturday);
}
}
输出
0
1
2
3
4
5
6
上面的程序编译并成功运行,得到所需的输出。我相信您一定已经意识到这需要多少努力;您必须在标识每个工作日的变量旁边输入“=”号和值。C# 提供了一种便捷的方式来完成这项工作,那就是枚举!所以,我们来谈谈枚举。我们将使用枚举来编写上面的程序。
P3.cs
enum WeekDays
{
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
class Demo
{
public static void Main()
{
System.Console.WriteLine(WeekDays.Sunday);
System.Console.WriteLine(WeekDays.Monday);
System.Console.WriteLine(WeekDays.Tuesday);
System.Console.WriteLine(WeekDays.Wednesday);
System.Console.WriteLine(WeekDays.Thursday);
System.Console.WriteLine(WeekDays.Friday);
System.Console.WriteLine(WeekDays.Saturday);
}
}
输出
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
太棒了!多么详细的输出!让我们花点时间看看这个程序。枚举允许我们创建一种新的数据类型。在上面的程序中,您可以看到使用 enum 创建了一个名为 WeekDays 的数据类型。枚举可以被认为是类的静态对象。这就是为什么我们允许仅使用枚举名称 WeekDays 来访问枚举中的元素,例如 WeekDays.Sunday,其中 WeekDays 是枚举的名称,Sunday 是枚举 WeekDays 的一个元素。在 WriteLine() 方法中,当我们传递枚举中的元素,如 enumName.elementName(即 WeekDays.Sunday)时,返回的输出是元素名称(即本例中的 Sunday)。上面程序的输出证明了这一点。
那么,我们如何获得数字输出呢?
P4.cs
enum WeekDays
{
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
class Demo
{
public static void Main()
{
System.Console.WriteLine((int)WeekDays.Sunday);
System.Console.WriteLine((int)WeekDays.Monday);
System.Console.WriteLine((int)WeekDays.Tuesday);
System.Console.WriteLine((int)WeekDays.Wednesday);
System.Console.WriteLine((int)WeekDays.Thursday);
System.Console.WriteLine((int)WeekDays.Friday);
System.Console.WriteLine((int)WeekDays.Saturday);
}
}
输出
0
1
2
3
4
5
6
为了获得 WeekDays.Sunday 的整数等效值,我们将 WeekDays.Sunday 强制转换为整数,并将其作为参数传递给 WriteLine() 方法。正如输出所示,枚举的第一个元素默认值为 0。后续元素以 1 的增量获得值。因此,Monday 的值为 1,Tuesday 的值为 2,Wednesday 的值为 3,依此类推。
P5.cs
enum InitialDays
{
Sunday,
Monday,
Tuesday,
Wednesday,
}
enum WeekDays : InitialDays
{
Thursday,
Friday,
Saturday
}
class Demo
{
public static void Main()
{
System.Console.WriteLine((int)WeekDays.Sunday);
System.Console.WriteLine((int)WeekDays.Monday);
System.Console.WriteLine((int)WeekDays.Tuesday);
System.Console.WriteLine((int)WeekDays.Wednesday);
System.Console.WriteLine((int)WeekDays.Thursday);
System.Console.WriteLine((int)WeekDays.Friday);
System.Console.WriteLine((int)WeekDays.Saturday);
}
}
输出
P5.cs(9,17): error CS1008: Type byte, sbyte, short, ushort, int, uint, long,
or ulong expected
错误!枚举不能派生自其他枚举。因此,不允许我们将枚举 WeekDays 派生自 InitialDays。那么,如果枚举不能派生自枚举,类可以派生自枚举吗?让我们找出来。
P6.cs
enum WeekDays
{
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
class Demo : WeekDays
{
public static void Main()
{
System.Console.WriteLine((int)WeekDays.Sunday);
System.Console.WriteLine((int)WeekDays.Monday);
System.Console.WriteLine((int)WeekDays.Tuesday);
System.Console.WriteLine((int)WeekDays.Wednesday);
System.Console.WriteLine((int)WeekDays.Thursday);
System.Console.WriteLine((int)WeekDays.Friday);
System.Console.WriteLine((int)WeekDays.Saturday);
}
}
输出
P6.cs(12,7): error CS0509: 'Demo': cannot derive from sealed type 'WeekDays'
P6.cs(1,6): (Location of symbol related to previous error)
错误!这是因为类不能派生自枚举。枚举被视为密封类,因此所有适用于密封类的规则也适用于枚举。
P7.cs
enum WeekDays
{
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}
class Demo
{
public static void Main()
{
System.Console.WriteLine((int)WeekDays.Sunday);
System.Console.WriteLine((int)WeekDays.Monday);
System.Console.WriteLine((int)WeekDays.Tuesday);
System.Console.WriteLine((int)WeekDays.Wednesday);
System.Console.WriteLine((int)WeekDays.Thursday);
System.Console.WriteLine((int)WeekDays.Friday);
System.Console.WriteLine((int)WeekDays.Saturday);
}
}
输出
P7.cs(10,4): error CS0102: The type 'WeekDays' already contains a definition
for 'Sunday'
P7.cs(3,4): (Location of symbol related to previous error)
错误!这是因为枚举,就像类一样,不能包含两个具有相同名称的成员。
P8.cs
enum WeekDays
{
Sunday=10,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
class Demo
{
public static void Main()
{
System.Console.WriteLine((int)WeekDays.Sunday);
System.Console.WriteLine((int)WeekDays.Monday);
System.Console.WriteLine((int)WeekDays.Tuesday);
System.Console.WriteLine((int)WeekDays.Wednesday);
System.Console.WriteLine((int)WeekDays.Thursday);
System.Console.WriteLine((int)WeekDays.Friday);
System.Console.WriteLine((int)WeekDays.Saturday);
}
}
输出
10
11
12
13
14
15
16
我们允许为枚举的成员指定常量值。在上面的程序中,我们为枚举的第一个成员(Sunday)指定了值 10。后续成员的值比前一个成员的值大一。这正是输出所示。
P9.cs
enum WeekDays
{
Sunday,
Monday,
Tuesday,
Wednesday=10,
Thursday,
Friday,
Saturday
}
class Demo
{
public static void Main()
{
System.Console.WriteLine((int)WeekDays.Sunday);
System.Console.WriteLine((int)WeekDays.Monday);
System.Console.WriteLine((int)WeekDays.Tuesday);
System.Console.WriteLine((int)WeekDays.Wednesday);
System.Console.WriteLine((int)WeekDays.Thursday);
System.Console.WriteLine((int)WeekDays.Friday);
System.Console.WriteLine((int)WeekDays.Saturday);
}
}
输出
0
1
2
10
11
12
13
重申一下,我们允许为枚举的成员指定常量值。在上面的程序中,枚举的第一个成员 Sunday 默认值为 0。后续成员的值比前一个成员的值大一。因此,Monday 的值为 1,Tuesday 的值为 2。下一个成员 Wednesday 被显式赋值为 10。这正是输出所示。后续成员的值比前一个成员的值大一。这正是输出所示。
P10.cs
enum WeekDays
{
Sunday = 10,
Monday = 10,
Tuesday = 10,
Wednesday = 10,
Thursday = 10,
Friday = 10,
Saturday = 10
}
class Demo
{
public static void Main()
{
System.Console.WriteLine((int)WeekDays.Sunday);
System.Console.WriteLine((int)WeekDays.Monday);
System.Console.WriteLine((int)WeekDays.Tuesday);
System.Console.WriteLine((int)WeekDays.Wednesday);
System.Console.WriteLine((int)WeekDays.Thursday);
System.Console.WriteLine((int)WeekDays.Friday);
System.Console.WriteLine((int)WeekDays.Saturday);
}
}
输出
10
10
10
10
10
10
10
允许显式为枚举的成员分配相同的值。这正是程序输出所示。
P11.cs
enum WeekDays
{
Sunday = 10000000000,
Monday = 10,
Tuesday = 10,
Wednesday = 10,
Thursday = 10,
Friday = 10,
Saturday = 10
}
class Demo
{
public static void Main()
{
}
}
输出
a.cs(4,13): error CS0266: Cannot implicitly convert type 'long' to 'int'. An'
explicit conversion exists (are you missing a cast?)
这里支持的枚举的底层数据类型是 int。如果我们尝试超出底层数据类型 int 所支持的值的范围,我们会得到一个与我们将 int 初始化为超出其容量的值时获得的错误类似的错误。在上面的程序中,我们尝试将 10000000000 存储到 Sunday 中。Sunday 的底层数据类型是 int。int 变量可以存储小于 10000000000 的值。因此,我们会收到错误!
有两种方法可以修复上述程序中的错误。第一种(也是显而易见的方法)是在 Sunday 中存储一个小于 10000000000 的值。
P12.cs
enum WeekDays
{
Sunday = 100,
Monday = 10,
Tuesday = 10,
Wednesday = 10,
Thursday = 10,
Friday = 10,
Saturday = 10
}
class Demo
{
public static void Main()
{
}
}
第二种方法是使用一种底层数据类型,其容量足以容纳 10000000000 这么大的值。这正是以下程序所做的。
P13.cs
enum WeekDays : long
{
Sunday = 10000000000,
Monday = 10,
Tuesday = 10,
Wednesday = 10,
Thursday = 10,
Friday = 10,
Saturday = 10
}
class Demo
{
public static void Main()
{
}
}
在上面的程序中,从 Sunday 到 Saturday 的枚举成员变量的整数类型是 long。
P14.cs
enum WeekDays
{
Sunday = 10,
Monday = Sunday,
Tuesday = Monday,
Wednesday = Tuesday,
Thursday = Wednesday,
Friday = Thursday,
Saturday = Friday
}
class Demo
{
public static void Main()
{
System.Console.WriteLine((int)WeekDays.Sunday);
System.Console.WriteLine((int)WeekDays.Monday);
System.Console.WriteLine((int)WeekDays.Tuesday);
System.Console.WriteLine((int)WeekDays.Wednesday);
System.Console.WriteLine((int)WeekDays.Thursday);
System.Console.WriteLine((int)WeekDays.Friday);
System.Console.WriteLine((int)WeekDays.Saturday);
}
}
输出
10
10
10
10
10
10
10
没有什么能阻止我们用预定义的枚举成员来定义枚举的成员。换句话说,在上面的程序中,我们允许定义一个枚举成员 Monday,它具有预定义的成员 Sunday。
P15.cs
enum WeekDays
{
Sunday = 10,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
class Demo
{
public static void Main()
{
WeekDays.Sunday = 36;
System.Console.WriteLine((int)WeekDays.Sunday);
}
}
输出
P15.cs(16,7): error CS0131: The left-hand side of an assignment must be a
variable, property or indexer
枚举成员的值不能改变。它表现得像一个常量。在上面的程序中,我们不能在 Main() 中更改枚举成员 Sunday 的值。它表现得像一个常量。
P16.cs
enum WeekDays
{
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
class Demo
{
public static void Main()
{
System.Console.WriteLine(WeekDays.Wednesday.CompareTo(WeekDays.Sunday));
System.Console.WriteLine(WeekDays.Wednesday.CompareTo(
WeekDays.Wednesday));
System.Console.WriteLine(WeekDays.Wednesday.CompareTo(
WeekDays.Saturday));
}
}
输出
1
0
-1
如果您需要比较枚举中的成员怎么办?您可能想知道枚举成员是否大于、小于或等于另一个正在考虑的枚举成员。为了实现这一点,我们使用了一个名为 CompareTo() 的方法。此方法属于 Enum 类。枚举派生自 Enum 类。由于在我们的枚举 WeekDays 中 Wednesday 大于 Sunday,因此输出为 1。类似地,由于 Wednesday 等于 Wednesday,输出为 0。同样,由于 Wednesday 小于 Saturday,输出为 -1。
P17.cs
enum WeekDays
{
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
class Demo
{
public static void Main()
{
System.Console.WriteLine(WeekDays.Wednesday.ToString());
}
}
输出
Wednesday
我们可以使用 toString() 函数将枚举成员转换为字符串。所以,让我们将枚举的所有成员都转换为字符串。
P18.cs
enum WeekDays
{
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
class Demo
{
public static void Main()
{
System.Console.WriteLine(WeekDays.Sunday.ToString());
System.Console.WriteLine(WeekDays.Monday.ToString());
System.Console.WriteLine(WeekDays.Tuesday.ToString());
System.Console.WriteLine(WeekDays.Wednesday.ToString());
System.Console.WriteLine(WeekDays.Thursday.ToString());
System.Console.WriteLine(WeekDays.Friday.ToString());
System.Console.WriteLine(WeekDays.Saturday.ToString());
}
}
输出
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
如果枚举有 1000 个成员,您还会遵循上述方法吗?当然不会,因为执行键入多个 WriteLine()
调用是一项非常繁重的工作。相反,下面的程序提供了一种更具可读性的方法。
P19.cs
enum WeekDays
{
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
class Demo
{
public static void Main()
{
string [] arr = WeekDays.GetNames(typeof(WeekDays));
foreach(string s in arr)
System.Console.WriteLine(s);
}
}
输出
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
静态函数 GetNames()
在字符串数组 arr
中返回枚举 WeekDays
内成员的字符串列表。foreach
循环打印字符串数组 arr
中的字符串。
P20.cs
enum WeekDays
{
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
class Demo
{
public static void Main()
{
System.Console.WriteLine(WeekDays.Monday + 100);
System.Console.WriteLine(100 + WeekDays.Monday);
}
}
输出
101
101
C# 允许将枚举成员与数字相加,反之亦然,因为重载的加法运算符已重载。
P21.cs
enum WeekDays
{
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
class Demo
{
public static void Main()
{
System.Console.WriteLine(WeekDays.Monday + WeekDays.Monday);
}
}
输出
P21.cs(16,34): error CS0019: Operator '+' cannot be applied to operands of
type 'WeekDays' and 'WeekDays'
错误!C# 不允许我们像上面程序中所示的那样将两个枚举成员相加。为了做到这一点,我们需要重载加法运算符。
那么,如果加法运算符不能直接与枚举成员一起工作,像 '=='、'<' 和 '>' 这样的运算符是否也自然工作,还是也必须重载它们?
P22.cs
enum WeekDays
{
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
class Demo
{
public static void Main()
{
System.Console.WriteLine(WeekDays.Monday == WeekDays.Monday);
System.Console.WriteLine(WeekDays.Monday != WeekDays.Monday);
System.Console.WriteLine(WeekDays.Monday < WeekDays.Tuesday);
System.Console.WriteLine(WeekDays.Monday > WeekDays.Tuesday);
}
}
输出
True
False
True
False
比较运算符已重载,可以像处理数字一样顺畅地与枚举的成员元素一起使用。那么,我们能否使用这些比较运算符来比较来自不同系列的两个枚举?让我们找出来。
P23.cs
enum WeekDays
{
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
enum Days
{
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
class Demo
{
public static void Main()
{
System.Console.WriteLine(WeekDays.Monday == Days.Monday);
}
}
输出
P23.cs(28,32): error CS0019: Operator '==' cannot be applied to operands of
type 'WeekDays' and 'Days'
真糟糕!比较运算符不适用于属于不同枚举的成员。