枚举类型实践
分类索引:C# 语言和运行时剖析--前言
枚举类型
概念:
- 定义:枚举类型提供了一组"符号名称/值"配对。
示例如下:
private enum Color /* : byte */ { White, // Assigned a value of 0 Red, // Assigned a value of 1 Green, // Assigned a value of 2 Blue, // Assigned a value of 3 Orange, // Assigned a value of 4 }
- 说明:
- 意义:枚举类型的意义在于使程序更容易编写,阅读和维护。
- 类型:每个枚举类型都直接从System.Enum派生,而System.Enum从System.ValueObject派生,所以枚举类型属于值类型。
- 实践注意:枚举类型跟一般的值类型一样,使用和理解相对简单。同样,跟一般的值类型一样,在操作中要尽量避免装箱。
- 基础类型:每个枚举类型都对应一个基础类型,用于存储枚举类型对象的值。此基础类型也必须是一个简单值类型,我们可以使用 byte, sbyte, short, ushort, int(默认)等值类型作为枚举类型的基础类型。
- 基础类型选择:
- 枚举类型对应的基础类型默认为int,但也可以自己定义,定义方法如下:
//将枚举的基本类型设定为byte,取代默认的Int。 private enum Color : byte { White, // Assigned a value of 0 Red, // Assigned a value of 1 Green, // Assigned a value of 2 Blue, // Assigned a value of 3 Orange, // Assigned a value of 4 }
- 枚举类型一般能够操作对应的基础类型所具有的操作符和大多数方法,操作符例如(==, !=, <, >, <=, >=, + , -, *, /)等。
- 常用方法重载
- ToString()方法:默认的枚举类型ToString()方法,将会返回枚举类型对象的当前符号名称。 例如:Color.Red.ToString() 将返回"Red"。
位标志
概念:
- 意义:使用位标志,可以在定义的枚举类型生成的对象之间使用或操作,来生成包含多个枚举对象特性的枚举对象。
- 说明:
- 使用方法如下:
[Flags] // The C# compiler allows either "Flags" or "FlagsAttribute". public enum Actions { Read = 0x0001, Write = 0x0002, Delete = 0x0004, Query = 0x0008, Sync = 0x0010 }
- 实践中注意:
- 定义时需要注意,不能依数字顺序定义枚举元素的基础值,而应该留出按位或操作的空间。
- 使用位标志的枚举对象使用ToString()方法时,会返回枚举对象符号名称自动连接在一起的数组。例如:
Actions actions = Actions.Read | Actions.Write; // 0x0003 Console.WriteLine(actions.ToString()); // "Read, Write"
自定义常用扩展方法
以上一节定义的枚举 Actions 为例,扩展出一些常用的 Enum 操作。(对具有位标志的枚举类型有效)
internal static class ActionsExtensionMethods { //判断枚举对象flags中是否包含枚举值flagTpTest public static Boolean IsSet(this Actions flags, Actions flagToTest) { if (flagToTest == 0) throw new ArgumentOutOfRangeException("flagToTest", "枚举值不能为 0"); return (flags & flagToTest) == flagToTest; } //判断枚举对象flags中是否不包含枚举值flagTpTest public static Boolean IsClear(this Actions flags, Actions flagToTest) { if (flagToTest == 0) throw new ArgumentOutOfRangeException("flagToTest", "枚举值不能为 0"); return !IsSet(flags, flagToTest); } //判断枚举对象flags中是否包含在枚举对象flagToTest中 public static Boolean AnyFlagsSet(this Actions flags, Actions flagToTest) { return (flags & flagToTest) != 0; } //将枚举对象setFlags加入另一个对象flags public static Actions Set(this Actions flags, Actions setFlags) { return flags | setFlags; } //将枚举对象clearFlags加入另一个对象flags中清除 public static Actions Clear(this Actions flags, Actions clearFlags) { return flags & ~clearFlags; } }