FlagsAttribute特性的使用還是很常見的,他只能應(yīng)用于Enum枚舉數(shù),下面是官方文檔的說明
(官方文檔:https://docs.microsoft.com/en-us/dotnet/api/system.flagsattribute?view=netframework-4.7.2)
Indicates that an enumeration can be treated as a bit field; that is, a set of flags.
用于表明一個(gè)枚舉可以當(dāng)作位標(biāo)志來處理.即一組標(biāo)志。簡單說:當(dāng)我們在使用枚舉的值與值之間進(jìn)行組合的時(shí)候(按位OR),F(xiàn)lags屬性可以給我們提供更直觀的格式化輸出(以字符串的形式輸出每個(gè)枚舉值)方便我們調(diào)試,即改變了System.Enum的ToString和Format的行為。
枚舉Enumerationk中定義的值通常是互斥的,比如方向,顏色,我們在只涉及到一種值的情況下,不需要考慮,但有些需求是會(huì)出現(xiàn)值與值之間存在可能的組合關(guān)系(combination),而且這種需求會(huì)在開發(fā)中非常的實(shí)用。
比如前面講過的反射(Reflection),我在通過字符串搜索成員的時(shí)候,需要指定BindingFlags(枚舉),我可能要同時(shí)包含Instance,Public,NoPublic,DeclaredOnly等等多個(gè)條件,這時(shí)候使用位操作是最簡單的方法。而使用FlagsAttribute可以給我們帶來更多的便利性(當(dāng)然實(shí)現(xiàn)位操作他不是必要的)
實(shí)現(xiàn)元素的組合,要對枚舉(Ennumeration)的值有要求,必須是2的N次冪,如1,2,4,8.....
這樣定義,每一個(gè)值都占有一個(gè)獨(dú)立的位,相當(dāng)于開關(guān),不會(huì)重疊,如下圖:

通過位|(OR)操作符,將需要的位打開,如:
public enum Vegetables
{
Cabbage = 1<<0,
Carrot = 1<<1,
Cuke = 1<<2,
Potato = 1<<3,
}
......
Vegetables vegetables = Vegetables.Cabbage | Vegetables.Carrot | Vegetables.Cuke | Vegetables.Potato;
//vegetables里同時(shí)包含了4種蔬菜,結(jié)果是:15,如圖所示:

這時(shí)候在控制臺(tái)輸出vegetables的值,打印出來15,因?yàn)?5這個(gè)值在枚舉中并沒有定義過,但通常這種輸出的值并不利于我們調(diào)試,我們無法馬上知道15或是其它值是由哪些值組合而來的,我們希望能夠更直觀的看到他們,在這里使用FlagsAttribute可以對位標(biāo)志的值提供更好的格式化輸出,以字符串的形式呈現(xiàn)。
如我們將枚舉修改如下:
[Flags]//添加Flags屬性
public enum Vegetables
{
Cabbage = 1<<0,
Carrot = 1<<1,
Cuke = 1<<2,
Potato = 1<<3,
}
這時(shí)候再輸出vetegables的值,控制臺(tái)會(huì)輸出如下:
Cabbage, Carrot, Cuke, Potato
這樣的結(jié)果才方便我們?nèi)フ{(diào)試.
在將這些值組合起來之后,我如何驗(yàn)證我是否包含了哪個(gè)值?即是否打開了哪個(gè)開關(guān)?
通過位&(AND)操作符
bool containCarrot = (vegetables&Vegetables.Carrot) == Vegetables.Carrot;
如圖:

二進(jìn)制1111和0010進(jìn)行位&運(yùn)算,結(jié)果是0010,Carrot位是打開的
如何關(guān)閉已經(jīng)打開的位標(biāo)志?
實(shí)際上就是將該位設(shè)置為0.比如我要關(guān)閉(刪除)Carrot這個(gè)值
代碼如下:
vegetables &= (~Vegetables.Carrot);
1111&=(~0010)=1111&=1101
結(jié)果為:13(Cabbage, Cuke, Potato)
(這里就不再上圖了)
位標(biāo)志的用途非常多,多條件的需求,除了上面說到的反射(多條件查詢BindingFlags),比如主角的被動(dòng)技能,加速,回血,無敵,防御力,xx力提升等等,可以同時(shí)作用于角色,通過位標(biāo)志的組合可以很方便的實(shí)現(xiàn)該功能.
到此為止,如果大家發(fā)現(xiàn)有什么不對的地方,歡迎指正,共同提高,感謝您的閱讀!
編輯于2018.7.12
--閑言碎語

(最近知了猴又出來了,每年都要拿著手電筒去樹上找,這是小時(shí)候最快樂的趣事兒之一,那時(shí)候會(huì)抓回來炸著吃,飛來飛去的就用蜘蛛網(wǎng)或塑料袋做成的捕捉工具來抓,然后烤著吃,味道非常香...)