15.1 枚舉類型 枚舉定義的符號是常量值. C 編譯器編譯時,會用數值替換符號,不再引用定義了符號的枚舉類型.可能會出現一些版本問題. Enum.IsDefined(Type enumType, object value) 方法被經常用於參數校驗: IsDefined 方法必須慎用. 首先, Is ...
15.1 枚舉類型
- 枚舉定義的符號是常量值. C#編譯器編譯時,會用數值替換符號,不再引用定義了符號的枚舉類型.可能會出現一些版本問題.
Enum.IsDefined(Type enumType, object value)方法被經常用於參數校驗:
public void SetColor(ConsoleColor c) { if (!Enum.IsDefined(typeof(ConsoleColor), c)) { throw new ArgumentOutOfRangeException(nameof(c), c, "無效顏色值"); } }
IsDefined方法必須慎用. 首先, IsDefined總是區分大小寫;其次,IsDefined相當慢,因為它在內部使用了反射.
15.2 位標誌
示例代碼:
[Flags] public enum FileAttributes { ReadOnly = 1, Hidden = 2, System = 4, Directory = 16, ...... } static void Main(string[] args) { //判斷文件是否隱藏 String file = Assembly.GetEntryAssembly().Location; FileAttributes attributes = File.GetAttributes(file); Console.WriteLine("Is {0} hidden? {1}", file, (attributes & FileAttributes.Hidden) != 0); //使用 HasFlag 方法(不推薦) Console.WriteLine("Is {0} hidden? {1}", file, attributes.HasFlag(FileAttributes.Hidden)); //設置只讀和隱藏特性 File.SetAttributes(file, FileAttributes.ReadOnly | FileAttributes.Hidden); }
- 避免使用 HasFlag,因為會裝箱.
永遠不要對位標誌枚舉類型使用 IsDefined 方法. 因為無論傳入數字或字元串,都只能進行簡單匹配,通常會返回False.
15.3 向枚舉類型添加方法
本身不能添加方法,但是可通過"擴展方法"實現
// flags 中是否包含 flagToTest public static bool IsSet(this FileAttributes flags, FileAttributes flagToTest) { if (flagToTest == 0) throw new ArgumentOutOfRangeException(nameof(flagToTest), "Value must not be 0"); return (flags & flagToTest) == flagToTest; } // flags 中是否不包含 flagToTest public static bool IsClear(this FileAttributes flags, FileAttributes flagToTest) { if (flagToTest == 0) throw new ArgumentOutOfRangeException(nameof(flagToTest), "Value must not be 0"); return !IsSet(flags, flagToTest); } // flags 中是否包含 testFlags 中的任何一個位標誌 public static bool AnyFlagsSet(this FileAttributes flags, FileAttributes testFlags) { return (flags & testFlags) != 0; } //將 setFlags 中包含的位標誌,添加到 flags 中 public static FileAttributes Set(this FileAttributes flags, FileAttributes setFlags) { return flags | setFlags; } //從 flags 中清除 指定的位標誌(clearFlags) public static FileAttributes Clear(this FileAttributes flags, FileAttributes clearFlags) { return flags & ~clearFlags; } //遍歷 flags 中包含的位標誌 public static void ForEach(this FileAttributes flags, Action<FileAttributes> processFlag) { if (processFlag == null) throw new ArgumentNullException(nameof(processFlag)); for (UInt32 bit = 1; bit != 0; bit <<= 1) { UInt32 temp = ((UInt32)flags) & bit; if (temp != 0) processFlag((FileAttributes)temp); } }