將不確定變為確定~整形變量是否可以進行(xing)位運算(像枚舉類型一樣(yang))
如果(guo)您看(kan)到這個題目,覺得有點怪,那說(shuo)明你是一個高人,最起碼比我高的多,呵呵。
前幾天做了一個公用后臺管理系統的項目,其中有一個地方涉及到權限管理的,即為每一個按鈕賦一個權限,然后它權限匯總到角色表里,即一種角色有一些操作權限
,表結構如下:
我們(men)看(kan)到OperatorAuthority就是操作(zuo)權(quan)限的(de)(de)意(yi)思,它是個(ge)(ge)int類(lei)型的(de)(de),一個(ge)(ge)role有一個(ge)(ge)OperatorAuthority,那(nei)我們(men)應該怎么把多個(ge)(ge)權(quan)限存儲到OperatorAuthority字段(duan)里呢?
這時(shi),我想到了枚舉類型的位運算,所以我把權限枚舉設計成了這樣:
1 [Flags] 2 public enum UserOperatorRole 3 { 4 #region 通用操作權限 5 6 /// <summary> 7 /// 沒有任何操(cao)作(zuo)權限 8 /// </summary> 9 [Description("沒有權限")] 10 NoneAny = 1, 11 /// <summary> 12 /// 查看(kan)事件(jian) 13 /// </summary> 14 [Description("查看事件")] 15 ReadEvent = 2, 16 /// <summary> 17 /// 添(tian)加事(shi)件(jian) 18 /// </summary> 19 [Description("添加事件(jian)")] 20 AddEvent = 4, 21 /// <summary> 22 /// 修改事件 23 /// </summary> 24 [Description("修(xiu)改(gai)事件")] 25 ModifyEvent = 8, 26 /// <summary> 27 /// 刪除事件 28 /// </summary> 29 [Description("刪(shan)除(chu)事件")] 30 DeleteEvent = 16, 31 /// <summary> 32 /// 審批 33 /// </summary> 34 [Description("審批")] 35 ApproveEvent = 32 36 37 #endregion 38 39 40 41 42 }
然后在存儲時,使用枚舉的位運算,對它進行求和即可,如查看事和修改事件的結果被存儲為10,即它只能是2和8相加的結果,如果希望了解更多位運算,可以查看我的這篇文章
這(zhe)樣(yang)的(de)設(she)計,對于單個項(xiang)目是沒(mei)有任何問(wen)題的(de),如果希望添(tian)加一(yi)種(zhong)新的(de)功(gong)能,如“訂閱”,我們只(zhi)要(yao)修改(gai)這(zhe)個枚舉類,再為它添(tian)加一(yi)種(zhong)訂閱的(de)邏輯即(ji)可。(當然,這(zhe)不符合開閉原則了)
但我(wo)設計(ji)的(de)偏偏是一個(ge)(ge)“通用(yong)的(de)系(xi)(xi)統(tong)(tong)”,即(ji)可(ke)能會有多個(ge)(ge)不同的(de)項(xiang)目(mu)去引(yin)用(yong)這(zhe)個(ge)(ge)系(xi)(xi)統(tong)(tong),這(zhe)個(ge)(ge)系(xi)(xi)統(tong)(tong)相當(dang)于一個(ge)(ge)底層的(de)核心系(xi)(xi)統(tong)(tong),這(zhe)時問題就來了,系(xi)(xi)統(tong)(tong)A的(de)權限(xian)(xian)需要添加一個(ge)(ge)“撤單”權限(xian)(xian),而系(xi)(xi)統(tong)(tong)B需要有一個(ge)(ge)“發布產(chan)品(pin)”及“管(guan)理產(chan)品(pin)”的(de)權限(xian)(xian),這(zhe)下子我(wo)也(ye)完蛋了,這(zhe)種需求被不斷的(de)添加進(jin)來,我(wo)可(ke)怎么辦呀!
主角登場了,整形也(ye)來個們運(yun)算吧,首先我把所有公(gong)用(yong)權限進(jin)行統計,放(fang)在一張表(biao)里,如果其它系統有新需求,在它的權限表(biao)里繼續添加(jia)即可(ke),表(biao)結構(gou)如下:
這樣(yang)的(de)設計,我(wo)(wo)認為完成了,但對于一個int32類型(xing)來說,它是(shi)否也(ye)可以支持按位(wei)計算(suan)呢?我(wo)(wo)又一想(xiang),枚舉類型(xing)本來就是(shi)繼(ji)承(cheng)int,short,long,byte等整形類型(xing)的(de),所以,我(wo)(wo)認識int32也(ye)完全可以支持位(wei)運算(suan),結果我(wo)(wo)的(de)測試表(biao)明我(wo)(wo)的(de)想(xiang)法(fa)是(shi)正確的(de),呵呵。
這時(shi),我們(men)通(tong)(tong)用按鈕的建立,就(jiu)變成(cheng)了這樣(yang)(yang)(yang),接收一(yi)個(ge)Enum這個(ge)枚舉類型的統一(yi)基類,這樣(yang)(yang)(yang)不管A系(xi)(xi)統和B系(xi)(xi)統自定義什么(me)樣(yang)(yang)(yang)的枚舉,我都通(tong)(tong)通(tong)(tong)接受,呵呵。
1 /// <summary> 2 /// 按(an)(an)鈕對象,只產(chan)生按(an)(an)鈕,對按(an)(an)鈕的click等事件需要在具體頁面自己添加 3 /// </summary> 4 /// <param name="html"></param> 5 /// <param name="buttonName">按鈕ID</param> 6 /// <param name="displayName">按鈕顯示名(ming)稱</param> 7 /// <param name="userOperatorRole">按鈕(niu)權(quan)限</param> 8 /// <param name="buttonType">按鈕類(lei)型</param> 9 /// <returns></returns> 10 public static MvcHtmlString CreateButton(this HtmlHelper html, string buttonName, string displayName, Enum userOperatorRole, ButtonType buttonType) 11 { 12 var tag = new TagBuilder("input"); 13 tag.AddCssClass("button"); 14 tag.Attributes["Name"] = buttonName; 15 tag.Attributes["ID"] = buttonName; 16 tag.Attributes["Value"] = displayName; 17 tag.Attributes["Type"] = buttonType.ToString(); 18 if ((Convert.ToInt32(SessionAction.ReadSession("UserOperatorRole")) & Convert.ToInt32(userOperatorRole)) == 0) 19 { 20 tag.Attributes["disabled"] = "disabled"; 21 tag.AddCssClass("button gray"); 22 } 23 return MvcHtmlString.Create(tag.ToString()); 24 }
程序員(yuan)在開發(fa)時,枚舉類型(xing)(xing)起到了直觀,準確(que)和可讀(du)性強的(de)優點(dian),所以,對于一些固(gu)定的(de)少限的(de)元素集可以采用枚舉類型(xing)(xing)和存儲。
小知識(shi):Enum是(shi)枚舉類型的基類
Delegate是(shi)委托類(lei)型的基類(lei)