65.9K
CodeProject 正在变化。 阅读更多。
Home

C# 中的枚举

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.75/5 (97投票s)

2007年5月15日

6分钟阅读

viewsIcon

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'

真糟糕!比较运算符不适用于属于不同枚举的成员。

© . All rights reserved.