C#enum枚举解析(含IL解析)(一)

enum枚举用于存储命名的和神奇的内容。一般在collection、if和switch中使用enum枚举。

Enum枚举:

思考一下,一个项目存储有代表性的花,花可能会有紫色的颜色,一个枚举可以代表各种颜色---这比string类型更加强大。

Enum枚举用法:

在C#程序中,我们必须以类似于类的方式来指定一个枚举。然后我们可以在需要的地方重复使用它。枚举类似于int整数,添加了编译器检查。

Enum示例:

这是一个枚举示例,表达重要性的。枚举类型内部包含了一个枚举器列表。数值(像Trivial 和 Critical)是整数,从1到4.

Int: 枚举的底层默认值是int。当我们使用一个Importance变量时,我们正在使用的就是一个int值。

If:我们用包含if-else语句块的if语句测试枚举值。这个值是Critical,所以“True”打印出来了。

第一步:我们指定一个枚举变量并将它分配给Importance.Critical。这就像一个int,但是有特殊的约束。

第二步:我们用if语句测试枚举值,值是Critical,所以打印出来“True”;

 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 EnumDemo1
 9 {
10     class Program
11     {
12         enum Importance
13         { 
14             None,
15             Trivial,
16             Regular,
17             Important,
18             Critical
19         }
20 
21         static void Main(string[] args)
22         {
23             //Step 1:create an enum local.
24             Importance value = Importance.Critical;
25 
26             //Step 2:test against a known Importance value.
27             if (value == Importance.Critical)
28             {
29                 Console.WriteLine(true);
30             }
31         }
32     }
33 }

 

 

Parse用法

有时候我们有个string值,我们想要转换成一个等效的枚举值 。我们调用Enum.Prase泛型函数来完成这种转换。(注意:Enum.Prase泛型函数是.NET5.0里面的,Visual Studio 2010无法使用,所以我们更换一种方式)

 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 using System.Runtime;
 8 
 9 namespace EnumPraseDemo
10 {
11     class Program
12     {
13         enum PetType
14         { 
15             None,Cat,Dog
16         }
17 
18         static void Main(string[] args)
19         {
20             string test = "Baby";
21             //Get enum from string
22             PetType result = (PetType)Enum.Parse(typeof(PetType),test);
23             Console.WriteLine(result);
24         }
25     }
26 }

 

 这样产生了错误,因为Baby在PetType枚举中是不存在的,所以PetType无法完成转换,产生异常。

 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 using System.Runtime;
 8 
 9 namespace Enum.PraseDemo
10 {
11     class Program
12     {
13         enum PetType
14         { 
15             None,Cat,Dog
16         }
17 
18         static void Main(string[] args)
19         {
20             string test = "Dog";
21             //Get enum from string
22             PetType result = (PetType)Enum.Parse(typeof(PetType),test);
23             Console.WriteLine(result);
24         }
25     }
26 }

 

 第9行命名空间与第22行的Enum.Parse产生了冲突,所以一般命名空间中尽量少使用“.”号;

 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 using System.Runtime;
 8 
 9 namespace EnumPraseDemo
10 {
11     class Program
12     {
13         enum PetType
14         { 
15             None,Cat,Dog
16         }
17 
18         static void Main(string[] args)
19         {
20             string test = "Dog";
21             //Get enum from string
22             PetType result = (PetType)Enum.Parse(typeof(PetType),test);
23             Console.WriteLine(result);
24         }
25     }
26 }

 

 本次运行成功,输出为Dog

提示:使用.NET时调用内置函数进行转换(如果存在的话)通常是最好的方式。

 

 调试器:

我们检查了枚举在Visual Studio调试器中的样子。我们可以看到枚举每个都是独立的类型。调试器显示tagValue是Program.TagType类型。

 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 EnumDebuggerDemo
 9 {
10     class Program
11     {
12         enum TagType
13         { 
14             None,BoldTag,ItalicsTag,HyperlinkTag
15         }
16 
17         static void Main(string[] args)
18         {
19             //指定一个tag实例
20             TagType tagValue = TagType.BoldTag;
21             
22 
23             if (tagValue == TagType.BoldTag)
24             {
25                 Console.WriteLine("Bold");
26             }
27             if (tagValue == TagType.HyperlinkTag)
28             {
29                 Console.WriteLine("Not True");
30             }
31             Console.WriteLine("tagValue is the type :{0}", tagValue.GetType());
32             Console.WriteLine("ItalicsTag is the type :{0}", TagType.ItalicsTag.GetType());
33         }
34     }
35 }

 

 info:从上面示例可以看出 ,每个enum枚举类型都是独立的,我们无法尝试将TagType类型变为PetType类型。

枚举的优势:

使用枚举,常数是独立分开的。这种模块化设计可以使事情更加容易理解。很少会引入Bug。

考虑一下这个项目---颜色blue被认为拥有数值9001.我们可以将这个颜色储存在枚举中以便于维护。

 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 EnumAdvantageDemo
 9 {
10     enum CaseColor
11     {
12         Uncolored = 0,
13         Red = 8001,
14         Blue = 9001
15     }
16 
17     class Program
18     {
19         static void Main(string[] args)
20         {
21             //This makes sense to read.
22             Console.WriteLine("Color:{0},{1}",
23                               CaseColor.Blue,
24                               (int)CaseColor.Blue);
25             //This is more confuing to read.
26             Console.WriteLine("Color:{0},{1}",
27                             "Blue",
28                              9001);
29         }
30     }
31 }

 

 注:在Visual Studio中,枚举可以与IntelliSense一起使用。此功能将猜测您键入的值。我们只需按tab键,就选择我们想要的枚举类型。这是使用枚举的一个优势。

strings:

我们将在Console中显示枚举转换成strings。枚举值一直都有一个名称,比如TagType.None(在上面的例子中)。

为了打印出来枚举值,你可以在项目中调用枚举的ToString。另一种方法,比如Console.Writeline能自动调用ToString函数。

在内部,ToString调用使用了反射的函数来获取string表示方法。

 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 EnumStringsDemo
 9 {
10     class Program
11     {
12         enum Visibility
13         { 
14             None,
15             Hidden = 2 ,
16             Visible = 4
17         }
18 
19         enum AnimaoType
20         { 
21             None,
22             Cat =1,
23             Dog =2
24         }
25 
26         static void Main(string[] args)
27         {
28             //...Two enum variables
29             AnimaoType animal = AnimaoType.Dog;
30             Visibility visible = Visibility.Hidden;
31 
32             //...Use Console.WriteLine to print out heir values
33             Console.WriteLine(animal);
34             Console.WriteLine(visible);
35         }
36     }
37 }

 

 Switch:

我们经常将if语句和枚举一起使用。但是,switch是另一种选择。并且,switch有时会编译成更加高效的IL。

 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 EnumSwitchDemo
 9 {
10     class Program
11     {
12         enum FormatType
13         { 
14             None,
15             BoldFormat,
16             ItalicsFormat,
17             Hyperlink
18         }
19 
20         static void Main(string[] args)
21         {
22             //Test enum with switch method
23             FormatType formatValue = FormatType.None;
24             if (IsFormat(formatValue))
25             {
26                 //this is printed , as we receive true from IsFormat.
27                 Console.WriteLine("Error");
28             }
29 
30             formatValue = FormatType.ItalicsFormat;
31             if (IsFormat(formatValue))
32             {
33                 Console.WriteLine("True");
34             }
35         }
36 
37         static bool IsFormat(FormatType value)
38         {
39             switch (value)
40             {
41                 case FormatType.BoldFormat:
42                 case FormatType.ItalicsFormat:
43                     {
44                         //These 2 values are format values.
45                         return true;
46                     }
47                 default:
48                     { 
49                         //The argument is not a format value.
50                         return false;
51                     }
52             }
53         }
54     }
55 }

 

 IsFormat:这个方法就像一个过滤器,告诉我们一些关于枚举值设置的信息——它包含一个switch语句。我们可以在这里把逻辑分开,而不是重复自己。这有助于阐明程序逻辑。

posted @ 2022-08-14 11:53  chenlight  阅读(520)  评论(0编辑  收藏  举报