第三部分 基本类型:第15章 枚举类型和位标志

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));

 

posted @ 2014-06-20 16:29  IT浪潮之巅  阅读(180)  评论(0编辑  收藏  举报
   友情链接: 淘宝优惠券