實際上本章就只講枚舉類型,因為位標志本來就可以當做一個特殊的枚舉類型。
關於枚舉類型
枚舉類型是一種消滅魔法數字的好方法,使程序更容易編寫,閱讀和維護。
枚舉類型是值類型,然而有別於其它值類型,枚舉類型不能定義任何方法。除非用擴展方法。
然而正如我之前說到的,也許當你想用擴展方法的時候可以先考慮一下這個地方是否還適合用枚舉類型,又或者這個方法是否適合加在這個枚舉類型中。
在編譯枚舉類型時,C#編譯器已經將每個符號轉換成了類型的一個常量字段。
C#默認容納一個枚舉類型的值的基礎類型為int,而實際上也可以像下面一樣自定義:
enum 英雄類型:byte { 力量英雄, 敏捷英雄, 智力英雄 }
可以用System.Enum.GetUnderlyingType方法去獲取枚舉類型的值的基礎類型。然而這裡只能用一些基元類型,不能用FCL類型。
通常用的時候除了比較,也只有轉換為字符串來查看具體的選項(其它的格式化的輸出枚舉感覺真心用不到的樣子,所以這裡不列舉了):
英雄類型 heroType = 英雄類型.力量英雄; Console.WriteLine(heroType.ToString());//力量英雄
也可以用Enum的靜態方法GetValues返回一個數組,裡面是Enum的所有選項。
也可以用Enum的靜態方法IsDefined方法去查看枚舉類型中,一個值或者其常量值是否被定義了。(然而這很慢,因為裡面用了反射)
關於位標志
前面講到可以將位標志當做一個特殊的枚舉類型。
[ComVisible(true)] [Flags] public enum FileAttributes { ReadOnly = 1, Hidden = 2, System = 4, Directory = 16, Archive = 32, Device = 64, Normal = 128, Temporary = 256, SparseFile = 512, ReparsePoint = 1024, Compressed = 2048, Offline = 4096, NotContentIndexed = 8192, Encrypted = 16384, IntegrityStream = 32768, NoScrubData = 131072 }
以上類型中,1的二進制為1,2的二進制為10,4的二進制為100。
也就是說可以用每個二進制位來確認唯一性,這就是位標志的原理。
var tmp = FileAttributes.ReadOnly | FileAttributes.Hidden;//表示只讀且文件隱藏 if ((tmp & FileAttributes.ReadOnly) != 0) {//因為二進制1&1才為1,所以只要存在最後的數值一定不為1 Console.WriteLine("tmp 只讀"); }
查看上面的FileAttributes的定義,會發現有一個[Flags]特性,這個特性的作用就是當tmp.ToString()是"ReadOnly, Hidden"這個字符串。
如果沒有[Flags]特性,就會為具體的數值。
上面講得都是將枚舉類型和位標志轉換為字符串或者值,將字符串和值轉成枚舉類型或位標志可以用下面的方法:
Enum.TryParse<FileAttributes>("ReadOnly, Hidden", false, out tmp);//false為忽略大小寫,這裡為位標志,轉枚舉類型也差不多