枚举类型和位标志
一、枚举类型
1,编译枚举时,C#编译器把每个符号转换成类型的一个常量字段。例如将Color枚举类型看成以下代码
//编译枚举时,c#编译器把每个符号转化成类型的一个常量字段 internal struct Color : System.Enum { //以下一些公共常量,它们定义了Color的符号和值 public const Color White = (Color) 0; public const Color Red = (Color) 1; //以下是一个公共实例字段,包含Color变量的值 //不能写代码来直接引用该字段 public Int32 value_; }
简单的说,枚举是一个结构,其中定义了一组常量字段和一个实例字段。常量字段会嵌入程序集的元数据中,并可以通过反射来访问
2,以下代码显示了如何声明一个基础类型为byte的枚举类型:
internal enum Color : byte { Red }
3,枚举的使用
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Drawing; namespace ConsoleApplication4 { class Program { static void Main(string[] args) { //返回用于容纳一个枚举类型的基础类型 //System.Int32 Console.WriteLine(Enum.GetUnderlyingType(typeof (ConsoleColor))); //输出枚举 Console.WriteLine(ConsoleColor.Blue);//Blue(常规格式) Console.WriteLine(ConsoleColor.Blue.ToString());//Blue(常规格式) Console.WriteLine(ConsoleColor.Blue.ToString("G"));//Blue(常规格式) Console.WriteLine(ConsoleColor.Blue.ToString("D"));//9(十进制格式) Console.WriteLine(ConsoleColor.Blue.ToString("X"));//00000009(十六进制格式) //获取枚举数组 var s = (ConsoleColor[]) Enum.GetValues(typeof (ConsoleColor)); foreach (var consoleColor in s) { Console.WriteLine("{0,5:D}\t{0:G}",consoleColor); } //输出Blue Console.WriteLine(Enum.GetName(typeof (ConsoleColor), 9)) ; //根据名称获取枚举值,没找到则抛异常 var color = (ConsoleColor) Enum.Parse(typeof (ConsoleColor), "Blue", true); //根据枚举值获取枚举 ConsoleColor c; Enum.TryParse<ConsoleColor>("9", true, out c); Console.WriteLine(c.ToString()); //输出Blue Enum.TryParse<ConsoleColor>("1231", true, out c); Console.WriteLine(c.ToString());//输出1231 //IsDefined方法判断数据对于某枚举是否合法 Console.WriteLine(Enum.IsDefined(typeof(ConsoleColor),1));//True 存在该值的枚举 Console.WriteLine(Enum.IsDefined(typeof(ConsoleColor), "Blue"));//True 存在该名称的枚举 Console.WriteLine(Enum.IsDefined(typeof(ConsoleColor), "blue"));//Flase 不存在该名称的枚举(区分大小写) Console.WriteLine(Enum.IsDefined(typeof(ConsoleColor), 1231));//Flase 不存在该值的枚举 Console.WriteLine(Enum.IsDefined(typeof(ConsoleColor), (ConsoleColor)1231));//Flase 不存在该值的枚举 Console.ReadKey(); } } }
IsDefined使用需谨慎,首先它总是执行区分大小写的查找;其次它相当慢,因为它在内部使用了反射
4,枚举的默认值
如果没有为枚举显示设置值得话,会有默认值
二、位标志
定义用于标识位标识的枚举类型时,当然应该显示为每个符号分配一个数值。强烈建议向枚举类型应用[Flags]特性
[Flags] public enum Status { Start=1, Order=2, End=4, All= Start| Order }
1,[Flags]特性
//Status s = (Status)5;
Status s = Status.Start | Status.End;//5 Console.WriteLine(s.ToString());//Start,End
Console.WriteLine(s.ToString("F"));//如果不加上flags特性可以使用“F”格式获得正确的字符串
调用ToString时,他会视图将数值转换为对应的符号。现在的数值是5,没有对应的符号。如果不加上[Flags]特性的话,就会显示5。加上该特性,就会把它视为一组为标志,由于5是由1(Start)和4(End)组成,所以ToString会生成字符串Start,End
2,位标志的使用
//由于Start被定义为1,所以"s"被初始化为1 Status s =(Status)Enum.Parse(typeof (Status), "Start", true); Console.WriteLine(s.ToString());//Start //由于Start和End已定义,所以"s1"初始化为5 Status s1; Enum.TryParse<Status>("Start,End", true, out s1); Console.WriteLine(s1.ToString());//Start,End //创建一个Status枚举实例,其值为7 Status s2 = (Status)Enum.Parse(typeof(Status),"7", true); Console.WriteLine(s2.ToString());//All,End
学习永不止境,技术成就梦想。