C# 枚举---分析与理解

在这篇文章中,我们会以示例的形式讨论枚举(Enums)。在文章末尾,你会懂得枚举是什么,什么时候使用枚举,如何使用枚举。

为什么我们需要枚举?

枚举是强类型的名称常量。我们用示例理解一下枚举。一个名为Employee类,Gender属性。Gender是整型。

1、0是未知性别;

2、1是男性;

3、2是女性;

 1 using System;
 2 using System.Collections.Generic;
 3 
 4 namespace EnumsDemo
 5 {
 6     class Program
 7     {
 8         static void Main(string[] args)
 9         {
10             //Create a collection to store employees
11             List<Employee> empList = new List<Employee>();
12             empList.Add(new Employee() { Name = "Anurag", Gender = 0});
13             empList.Add(new Employee() { Name = "Pranaya", Gender = 1 });
14             empList.Add(new Employee() { Name = "Priyanka", Gender = 2 });
15             empList.Add(new Employee() { Name = "Sambit", Gender = 3 });
16             
17             //Loop through each employees and print the Name and Gender
18             foreach (var emp in empList)
19             {
20                 Console.WriteLine("Name = {0} && Gender = {1}", emp.Name, GetGender(emp.Gender));
21             }
22 
23             Console.ReadLine();
24         }
25 
26         //This method is used to return the Gender 
27         public static string GetGender(int gender)
28         {
29             // The switch here is less readable because of these integral numbers
30             switch (gender)
31             {
32                 case 0:
33                     return "Unknown";
34                 case 1:
35                     return "Male";
36                 case 2:
37                     return "Female";
38                 default:
39                     return "Invalid Data for Gender";
40             }
41         }
42     }
43 
44     // 0 - Unknown
45     // 1 - Male
46     // 2 - Female
47     public class Employee
48     {
49         public string Name { get; set; }
50         public int Gender { get; set; }
51     }
52 }

 

 上述项目代码的缺点是可读性差,可维护性差。现在,我们看一下如何使用枚举进行整体替换,使项目代码具有更好的可读和可维护性。

首先,用枚举创建Gender

 

 修改GetGender函数方法,如下所示:

 

 像上面那样,我们用枚举代替了数字,可以使代码更加可读和可维护。

 

 “Gender.Unknown”会提示错误,无法将Gender.Unknown隐式转换为int。因此,需要强制转换,完整代码如下:

 

 1 using System;
 2 using System.Collections.Generic;
 3 
 4 namespace EnumsDemo
 5 {
 6     class Program
 7     {
 8         static void Main(string[] args)
 9         {
10             //Create a collection to store employees
11             List<Employee> empList = new List<Employee>();
12             empList.Add(new Employee() { Name = "Anurag", Gender = 0});
13             empList.Add(new Employee() { Name = "Pranaya", Gender = 1 });
14             empList.Add(new Employee() { Name = "Priyanka", Gender = 2 });
15             empList.Add(new Employee() { Name = "Sambit", Gender = 3 });
16             
17             //Loop through each employees and print the Name and Gender
18             foreach (var emp in empList)
19             {
20                 Console.WriteLine("Name = {0} && Gender = {1}", emp.Name, GetGender(emp.Gender));
21             }
22 
23             Console.ReadLine();
24         }
25 
26         //This method is used to return the Gender 
27         public static string GetGender(int gender)
28         {
29             // The switch here is now more readable and maintainable because 
30             // of replacing the integral numbers with Gender enum
31             switch (gender)
32             {
33                 case (int)Gender.Unknown:
34                     return "Unknown";
35                 case (int)Gender.Male:
36                     return "Male";
37                 case (int)Gender.Female:
38                     return "Female";
39                 default:
40                     return "Invalid Data for Gender";
41             }
42         }
43     }
44 
45     // 0 - Unknown
46     // 1 - Male
47     // 2 - Female
48     public class Employee
49     {
50         public string Name { get; set; }
51         public int Gender { get; set; }
52     }
53 
54     public enum Gender
55     {
56         Unknown,
57         Male,
58         Female
59     }
60 }

 

 所以,如果一个项目用的是一系列数字,可以考虑用枚举代替,这样程序代码会可读和可维护。

需要记住的枚举的几点

1、枚举是enumerations;

2、枚举是强类型的命名常量。因此,显式强制转换是需要将枚举类型转换成整型,反之亦然;同样地,一种类型的枚举不能隐式地赋值给另一种类型的枚举,尽管他们的成员的底层数值是一样的。

3、默认枚举的底层数据类型是int 。

4、枚举的第一个元素默认值为0,以1递增。

5、也可以自定义枚举的底层数据类型和数值。

6、枚举是值类型。

7、Enum关键字用于创建枚举类型,借鉴于Enum class ,枚举包含静态方法GetValues()和GetNames(),这两个函数能用于罗列枚举的底层类型和名称。

Gender枚举底层数据类型是short,数值从1开始,以1递增

 

 

 所以,这样看的话,Male值是2,Female值是3;枚举值不必须是连续的,任何有效的底层数值都是允许的,如下面这样:

 

 

 下面的枚举代码不是进行编译,因为short数据类型的最大值是32767

 

 

 注:可以用short.MaxValue来找出short所能支持的最大数值。

显式转换可以将枚举类型转换为整型,反之亦然

int i = Gender.Male;

上面代码不会编译,编译错误创建如下:Cannot implicitly convert type ‘Gender’ to ‘int’. An explicit conversion exists (are you missing a cast?)

Gender female = 2;

上面代码也不会编译,类似编译错误创建如下:The left-hand side of an assignment must be a variable, property or indexer

一种类型的枚举不能隐式赋值给另一种类型的枚举

尽管底层的数据类型是一样的,但是一种类型的枚举不能赋值给另一种类型的枚举。在下面的示例中,需要进行显式转换:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Drawing;
 6 using System.Windows.Forms;
 7 
 8 namespace Enums1
 9 {
10     class Program
11     {
12         static void Main(string[] args)
13         {
14             Gender gender = (Gender)Season.Summer;
15             Console.WriteLine("Gender.gender的值是{0}",gender);
16             Console.WriteLine("Gender.Male的值是{0}",(int)Gender.Female);
17             Console.WriteLine("Season.Summer的值是{0}",Season.Summer);
18             Console.ReadLine();
19         }
20         public enum Gender : int
21         { 
22             Unknown = 1,
23             Male = 2,
24             Female = 3
25         }
26         public enum Season : int
27         { 
28             Winter = 1,
29             Spring = 2,
30             Summer = 3
31         }
32     }
33 }
View Code

 

 了解GetValues()和GetNames()方法函数

 

 

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Drawing;
 6 using System.Windows.Forms;
 7 
 8 namespace Enums2
 9 {
10     class Program
11     {
12         static void Main(string[] args)
13         {
14             int[] Values = (int[])Enum.GetValues(typeof(Gender));
15             Console.WriteLine("Gender Enum Values");
16             Console.WriteLine("Gender的数据类型是{0}",typeof(Gender));
17             foreach (int value in Values)
18             {
19                 Console.WriteLine(value);
20             }
21             
22             Console.WriteLine();
23             string[] Names = Enum.GetNames(typeof(Gender));
24             Console.WriteLine("Gender Enum Names");
25             foreach (string Name in Names)
26             {
27                 Console.WriteLine(Name);
28             }
29             Console.ReadKey();
30         }
31         public enum Gender : int
32         { 
33             Unknow = 1,
34             Male =2,
35             Female =3
36         }
37     }
38 }
View Code

 

 不能从其它枚举继承

我们用以下示例理解一下枚举不能继承

 

 当我们编译的时候,会报错,如下:

 

 以上可见,一个枚举不能从其它枚举进行继承。但是,类可以继承枚举嘛?我们用示例看一下:

 1 using System;
 2 namespace EnumsDemo
 3 {
 4     class Program : WeekDays
 5     {
 6         static void Main(string[] args)
 7         {
 8             Console.WriteLine((int)WeekDays.Monday);
 9             Console.WriteLine((int)WeekDays.Sunday);
10             Console.WriteLine((int)WeekDays.Tuesday);
11             Console.WriteLine((int)WeekDays.Wednesday);
12             Console.WriteLine((int)WeekDays.Thursday);
13             Console.WriteLine((int)WeekDays.Friday);
14             Console.WriteLine((int)WeekDays.Saturday);
15             
16             Console.ReadKey();
17         }
18     }
19     
20     public enum WeekDays
21     {
22         Sunday,
23         Monday,
24         Tuesday,
25         Wednesday,
26         Thursday,
27         Friday,
28         Saturday
29     }
30 }
View Code

运行程序会有如下报错:

 

 上面的错误表明类也不能继承自枚举。这是因为枚举是封闭类,因此适用于封闭类的规则也适用于枚举。

复制枚举成员

让我们创建两个名称相同的枚举成员,如下示例

 1 using System;
 2 namespace EnumsDemo
 3 {
 4     class Program
 5     {
 6         static void Main(string[] args)
 7         {
 8             Console.WriteLine((int)Gender.Unknown);
 9             Console.WriteLine((int)Gender.Male);
10             Console.WriteLine((int)Gender.Female);           
11             Console.ReadKey();
12         }
13     }
14     
15     public enum Gender
16     {
17         Unknown,
18         Male,
19         Female,
20         Unknown
21     }
22 }

 

 依然会报错。枚举就像类,不能定义两个名称相同的成员。

posted @ 2022-03-24 23:03  chenlight  阅读(330)  评论(1编辑  收藏  举报