15.1 枚举类型
枚举类型定义了一组“符号名称/值”配对。
例如,以下Color类型定义了一组符合,每个符号表示一种颜色。
internal enum Color{ White, //赋值0 Red, //赋值1 Green, //赋值2 Blue, //赋值3 Orange //赋值4 }
枚举类型的好处:
枚举类型容易编写、阅读和维护。
枚举类型是强类型。
派生关系:
System.Object -> System.ValueType -> System.Enum -> 枚举类型
枚举类型是值类型,但和正常值类型的区别:
枚举类型不能定义任何方法、属性或事件。(可利用“扩展方法”模拟想枚举类型添加方法)
编译枚举类型时,C#编译器会把每个符号转换成类型的一个常量字段。
例如,编译器会把前面Color枚举类型看成是以下代码:
internal struct Color: System.Enum{ //以下是一些公共常量,它们定义了Color的符号和值 public const Color White = (Color) 0; public const Color Red = (Color) 1; public const Color Green = (Color) 2; public const Color Blue = (Color) 3; public const Color Orange = (Color) 4; //以下是一个公共实例字段,它包含一个Color变量的值, //不能写代码来直接引用这个实例字段 public Int32 value__; }
15.2 位标志
如调用System.IO.File类型的GetAttributes方法,会返回FileAttributes类型的一个实例。FileAttributes类型是基本类型为Int32的枚举类型,每一位都反映了文件的一项属性。
FileAttributes类型在FCL中的定义如下:
判断一个文件是否隐藏,可执行下面代码:
String file = Assembly.GetEntryAssembly().Location; FileAttributes attributes = File.GetAttributes(file); Console.WriteLine("Is {(0)} hidden?{1}",file,(attributes & FileAttributes.Hidden) !=0); 位标志表示一组位,位有on和off状态 而枚举表示单个数值
以下代码演示如何将一个文件的属性改为只读和隐藏:
File.SetAttributes(file,FileAttributes.ReadOnly | FileAttributes.Hidden);
定义用于标志位标志的枚举类型时,当然应该显示为每个符号分配一个数值。通常,每个符号都有单独的一个位处于on状态。此外,经常都要定义一个值为0的None符号。还可以定义一些代表常用组合的符号。另外,强烈建议向枚举类型应用System.FlagsAttributes这个定制attribute类型,如下所示:
因为Actions是枚举类型,所以在操作位标志枚举类型时,可以使用上一节描述的所有方法。不过,假如其中的一些方法的行为稍有区别,效果会更加理想。例如,假设有一下代码:
Acions actions = Actions.Read | Actions.Delete; //0x0005 Console.WriteLine(action.ToString()); //"Read, Delete"
调用ToString时,它会试图将数值转换为对应的符号。现在的数值是0x0005,它没哟对应的符号。不过,ToString方法检测到Actions类型上存在[Flag]这个attribute,所以ToString方法现在不会将该数值视为单独的值。相反,会把它视为一组位标志。由于0x0005由0x0001和0x0004组合而成,所以ToString会生成字符串"Read,Delete"。如果从Action类型中删除[Flags]这个attribute,ToString方法将返回"5"。
15.3 向枚举类型添加方法
可以利用C#的扩展方法功能向枚举类型模拟添加方法:
以下代码演示了如何调用其中的一些方法。从表面上看,似乎真的是在枚举类型上调用这些方法:
FileAttributes fa = FileAttributes.System; fa = fa.Set(FileAttributes.ReadOnly); fa = fa.Clear(FlieAttributes.System); fa.ForEach(f => Console.WriteLine(f));