FlagsAttribute是什么?

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ì)重疊,如下圖:

40596e8059b382e6ff79a1b6a55fa33.png

通過位|(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,如圖所示:

249cd997ee2862ecd9b7ced04212fc0.png

這時(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;

如圖:


37574caa2b7bddbe3bcfb65e5fa81c0.png

二進(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

--閑言碎語


e156177364ebf38d2c4b7c90ef239d6.png

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.編譯程序(1)gcc xx.c,他會(huì)默認(rèn)生成一個(gè)a.out的可執(zhí)行文件,在a.out所在目錄,執(zhí)行./a.o...
    萌面大叔2閱讀 1,425評論 0 1
  • 在一個(gè)方法內(nèi)部定義的變量都存儲(chǔ)在棧中,當(dāng)這個(gè)函數(shù)運(yùn)行結(jié)束后,其對應(yīng)的棧就會(huì)被回收,此時(shí),在其方法體中定義的變量將不...
    Y了個(gè)J閱讀 4,575評論 1 14
  • .bat腳本基本命令語法 目錄 批處理的常見命令(未列舉的命令還比較多,請查閱幫助信息) 1、REM 和 :: 2...
    慶慶慶慶慶閱讀 8,537評論 1 19
  • 主題模型為非監(jiān)督模型,且都需要構(gòu)造一個(gè)矩陣,推測的是隱含的主題或者模式(如偏好)。都會(huì)變換出對矩陣中縱橫兩個(gè)維度的...
    吹洞簫飲酒杏花下閱讀 998評論 0 1
  • 趁青春還剩下一點(diǎn)點(diǎn)的余溫,溫暖著你的眼淚,我不怕寒冷,迎著這歲月的風(fēng)。 谷雨節(jié)氣,春天已經(jīng)走到了最后,夏天就要來了...
    是丁二呀閱讀 203評論 0 1

友情鏈接更多精彩內(nèi)容