我不時看到以下枚舉: ide
[Flags] public enum Options { None = 0, Option1 = 1, Option2 = 2, Option3 = 4, Option4 = 8 }
我不明白[Flags]
屬性的確切做用。 ui
任何人均可以發表很好的解釋或榜樣嗎? 編碼
對於if ((x & y) == y)...
構造,我有些過於冗長,尤爲是若是x
AND y
都是複合標誌集,而且您只想知道是否存在任何重疊。 spa
在這種狀況下,您真正須要知道的是對bitmasked後是否存在非零值[1] 。 code
[1]參見Jaime的評論。 若是咱們確實是位屏蔽 ,咱們只須要檢查結果是不是確定的便可。 可是因爲
enum
能夠是負數,甚至與[Flags]
屬性結合使用時也很奇怪,所以對於!= 0
而不是> 0
進行編碼是防護性的。 orm
以@andnil的設置爲基礎... get
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace BitFlagPlay { class Program { [Flags] public enum MyColor { Yellow = 0x01, Green = 0x02, Red = 0x04, Blue = 0x08 } static void Main(string[] args) { var myColor = MyColor.Yellow | MyColor.Blue; var acceptableColors = MyColor.Yellow | MyColor.Red; Console.WriteLine((myColor & MyColor.Blue) != 0); // True Console.WriteLine((myColor & MyColor.Red) != 0); // False Console.WriteLine((myColor & acceptableColors) != 0); // True // ... though only Yellow is shared. Console.WriteLine((myColor & MyColor.Green) != 0); // Wait a minute... ;^D Console.Read(); } } }
結合答案https://stackoverflow.com/a/8462/1037948 (經過位移進行聲明)和https://stackoverflow.com/a/9117/1037948 (使用聲明進行組合),您能夠將之前的值進行位移而不是使用數字。 不必定推薦它,只是指出您能夠。 string
而不是: it
[Flags] public enum Options : byte { None = 0, One = 1 << 0, // 1 Two = 1 << 1, // 2 Three = 1 << 2, // 4 Four = 1 << 3, // 8 // combinations OneAndTwo = One | Two, OneTwoAndThree = One | Two | Three, }
您能夠聲明 io
[Flags] public enum Options : byte { None = 0, One = 1 << 0, // 1 // now that value 1 is available, start shifting from there Two = One << 1, // 2 Three = Two << 1, // 4 Four = Three << 1, // 8 // same combinations OneAndTwo = One | Two, OneTwoAndThree = One | Two | Three, }
用LinqPad確認:
foreach(var e in Enum.GetValues(typeof(Options))) { string.Format("{0} = {1}", e.ToString(), (byte)e).Dump(); }
結果是:
None = 0 One = 1 Two = 2 OneAndTwo = 3 Three = 4 OneTwoAndThree = 7 Four = 8
爲了擴展可接受的答案,在C#7中,可使用二進制文字來編寫枚舉標誌:
[Flags] public enum MyColors { None = 0b0000, Yellow = 0b0001, Green = 0b0010, Red = 0b0100, Blue = 0b1000 }
我認爲這種表示方式清楚地代表了標誌是如何在幕後工做的 。
使用標誌時,我常常聲明其餘「無」和「全部」項。 這些有助於檢查是否設置了全部標誌或沒有設置標誌。
[Flags] enum SuitsFlags { None = 0, Spades = 1 << 0, Clubs = 1 << 1, Diamonds = 1 << 2, Hearts = 1 << 3, All = ~(~0 << 4) }
用法:
Spades | Clubs | Diamonds | Hearts == All // true Spades & Clubs == None // true
更新2019-10:
從C#7.0開始,您可使用二進制文字,閱讀起來可能更直觀:
[Flags] enum SuitsFlags { None = 0b0000, Spades = 0b0001, Clubs = 0b0010, Diamonds = 0b0100, Hearts = 0b1000, All = 0b1111 }
標誌容許您在枚舉中使用位掩碼。 這使您能夠合併枚舉值,同時保留指定的值。
[Flags] public enum DashboardItemPresentationProperties : long { None = 0, HideCollapse = 1, HideDelete = 2, HideEdit = 4, HideOpenInNewWindow = 8, HideResetSource = 16, HideMenu = 32 }