13.2 位标记
开发人员通常要用到位标记(bit flag)集合.当我们调用System.IO.File类型的GetAttributes方法时,它会返回一个FileAttribute类型的实例.FileAttribute类型是一个基础类型为Int32的枚举类型,其每个位反映了文件的一个属性(attribute),FCL中FileAttribute类型定义如下:
[Flags,Serializable]
public enum FileAttributes {
ReadOnly = 0x0001,
Hidden = 0x0002,
System = 0x0004,
Directory = 0x0010,
Archive = 0x0020,
Device = 0x0040,
Normal = 0x0080,
Temporary = 0x0100,
SparseFile = 0x0200,
ReparsePoint = 0x0400,
Compressed = 0x0800,
Offline = 0x1000,
NotContentIndexed=0x2000,
Encrypted = 0x4000
}
当定义用于标识位标记的枚举类型时,我们应该显式地为每个符号赋予映射到单个位的数值.同时强烈建议大家在这样的枚举类型上应用System.FlagsAttribute定制特性,看下面的例子:
[Flags] //C#编译器允许我们使用"Flags"或者"FlagsAttribute"
enum Actions {
Read = 0x0001,
Write = 0x0002,
Delete = 0x0004,
Query = 0x0008,
Sync = 0x0010
}
由于Action仍是一个枚举类型,所以我们仍染可以使用前一节中描述的所有方法.当然,如果某些方法的行为稍微有一些不同的话就更好了,例如,假设我们有以下代码:
Actions actions= Actions.Read| Actions.Write; //0x0003
Console.WriteLine(actions.ToString()); //"Read.Write"
当ToString 方法被调用时,它会试图将actions表示的数值翻译为枚举类型中对应的符号.现在枚举实例actions的数值为0x0003,因此它没有对应的符号.但是ToString方法会检测到Actions类型上应用有[Flags]特性,它会据此把枚举数值看作是一组位标记、而非一个单独的数值.因为0x0003是由0x0001和0x0002组合而成的,Actions又定义了0x0001和0x0002,所以ToString方法将产生下面的字符串:"Read,Write".如果删除在Actions类型上应用的[Flags]特性,ToString将会见大地返回字符串"3".