前幾天看到一段代碼
int i = GetCount(para1 | para2);
咋一看有些莫名奇妙,怎麼傳參的時候帶了個或運算,其實這裡面是有講究的,查閱了各方資料, QQ群裡賴著大牛問,才搞明白。這個運算可以用來進行多項組合。
舉個例子,在設計權限的時候,你肯定會這樣設計,權限A,做什麼,權限B,做什麼,權限C,做什 麼...如此定義權限,在調用處理函數時,我們直接傳對應的權限Id就行,假設用戶甲有A權限,我很明 確得傳權限A的Id,用戶乙有B權限,我傳B權限的Id,這樣看來似乎是合理的。但是,如果用戶丙同時有 A權限和B權限怎麼辦呢,你可能會說,那我定義權限的時候定個AB’的權限好了,這樣凡是同時 有A和B權限的用戶傳AB’的Id就行了,我一開始也是這麼想的,不過,這個做法是不推薦的,也 是不巧妙的,假如還有用戶同時有ABC權限,或者BC權限,或者CD權限,那麼我就什麼事也不用干了, 就一直在給它定義類型了。
推薦的做法是,傳參用“|”運算組合,處理用“&”運算拆分,這樣, 調用者可以隨意組合,而對於處理者,則只定義最基本的單個處理“&”判斷即可。看 個例子:
定義一個枚舉表示權限類型:
public enum Privilege { Read = 0x01, Write = 0x02, Add = 0x04, Delete = 0x08, }
定義一個處理函數:
public void GetPrivilege(Privilege pri) { if ((pri & Privilege.Read) == Privilege.Read) { //do something } if ((pri & Privilege.Write) == Privilege.Write) { //do something } if ((pri & Privilege.Add) == Privilege.Add) { //do something } if ((pri & Privilege.Delete) == Privilege.Delete) { //do something } }
然後在其他地方調用:
... GetPrivilege(Privilege.Read); GetPrivilege(Privilege.Write); GetPrivilege(Privilege.Add); GetPrivilege(Privilege.Delete); GetPrivilege(Privilege.Read | Privilege.Write); GetPrivilege(Privilege.Write | Privilege.Add); GetPrivilege(Privilege.Read | Privilege.Write | Privilege.Add); ...
你會看到每次調用都會精准得執行。為什麼可以這樣呢,看我定義的枚舉,對應的值分別是
0x01
0x02
0x04
0x08
為什麼我不定義成0x01,0x02,0x03,0x04,這是就依賴於我一開始講的“|”和 “&”運算了,“|”或運算是只要有1方為1就為1,“&”與 運算是兩者都為1才為1,把0x01,0x02,0x04,0x08轉成2進制就是
0001
0010
0100
1000
任何兩個組合,都會在自己的位上變為1。之後再拆分,由於之前組合過,自然就能精准地定位了。 比如0x1和0x8組合,組合後就是1001,那麼之後通過“&”來拆分,當&0x1時就能 進去,&到0x8時也能進去,像這種0x01,0x02,0x04,0x08用行話講叫“開關位”,今天 在QQ群裡問人被人說,哎~丟銀啊~
如此,便能以不變應萬變,組合出任意結果,真是很方便啊。
作者: 熱卡
出處:http://www.cnblogs.com/zoexia/
查看本欄目