對列舉值(Enum)進行位操作(AND & OR)
這裡我們可以解釋為什麼第三個值ShowToolbox可以為4,5..而不能為3。
也就是說它的值不應該是前幾項值的複合值。【我的理解是 不能前幾位的和】
有一個比較簡單的方法就是用2的n次方來依次為每一項賦值,例如 1,2,4,8,16,32,64.....
對列舉值(Enum)進行位操作(AND & OR)
這是我在部落格園的第一篇隨筆,其實也不能說是隨筆只能算是一篇翻譯稿,呵呵,這個就是以後我在部落格園的主要隨筆方式了。
對列舉值(Enum)進行位操作(AND & OR)
對列舉值進行AND 和 OR 操作是 .Net 中最不常用的功能之一,在讀了本文之後你將會發覺它其實也是一個比較有用的功能。
在做專案的時候我們可能經常會碰到這樣一種情況:我們需要儲存一些boolean值,然後在我們定義的類裡面對應的新增一個Isxxxx 屬性。比如說使用者許可權物件(IsAdmin,IsUser,IsPowerUser等)。建立和檢查這樣的一些相關屬性,然後還要注意這些屬性之間的組合,隨著這樣的屬性數量的增加,我們會發覺編寫和維護程式碼的工作量會相當的大而且容易出錯。
對於以上情況位操作(AND和OR)就可以相當輕鬆的進行處理,注意AND和OR是位操作符,他們是在數字的二進位制表示層上進行操作。
如果你對二進位制數不熟悉,請先參考相關資料。
二進位制數上的操作有很多種,我們這裡只需要用到AND和OR.
列舉型別(Enum)中的所有值都是整數,把一個整數用二進位制進行表示的時候,我們可以把每一位都當作是一個boolean值,這樣一個整數就可以來儲存一個boolean值的列表。
為了可以方便的實現這個功能,我們規定在列舉物件當中儲存的值只能夠是2的冪。
下面我們舉個例子,我們定義一個列舉物件來決定到底把什麼調料放在Pizza上面。
< Flags() > Public Enum Toppings ‘注意需要Flags標記 表明是位編碼
None = 0 '務必定義一個等於0的列舉值
Pepperoni = 1
Mushrooms = 2
Onions = 4
Anchovies = 8
Peppers = 16
Pineapple = 32
End Enum
然後我們建立一個MakePizza的方法,它的輸入引數是 Toppings列舉值
MakePizza(UseToppings as Toppings)
在MakePizza方法內部我們首先定義一個列舉變數(MyToppings),對所有我們需要的值進行OR操作,然後賦值給它。
Dim MyToppings as Toppings
MyToppings = Mushrooms OR Onions OR Peppers
現在儲存在MyToppings中的值是22.
00000010 (Mushrooms - 2)
00000100 (Onions - 4)
00010000 (Peppers - 16)
--------―― OR
00010110 (22)
在MakePizza(UseToppings as Toppings)方法內部,我們需要判斷到底是什麼值產生了MyToppings(22)。
為了實現這個目的,我們把MyToppings與傳入的UseTopping進行AND操作。任何非零的操作結果代表一個True值。
現在我們來測試一下,如果傳入Pepperoni,
If UseToppings AND Toppings.Pepperoni Then
'新增 pepperonis
End If
操作結果是 0(false)
00010110 (UseToppings - 22)
00000001 (Pepperoni - 1)
-------- AND
00000000 (0)
如果傳入Onions
結果是true(大於0)
00010110 (UseToppings - 22)
00000100 (Onions - 4)
-------- AND
00000100 (4)
通過這樣的方法,我們可以節省了儲存我們要表示的物件的儲存空間(在資料庫當中或者記憶體當中)
我們不用建立Pepperoni, Onions, Mushrooms等的true/false列,只要儲存一個數字22就可以了
通過這個例子,大家可以舉一反三,比如說應用在使用者許可權上面(Edit, ReadOnly, Admin等)
你可以建立一個使用者許可權的列舉,然後把他們儲存在資料庫的一列上就可以了。
我們還可以在sql語句內部充分利用這個方便性,比如說
SELECT * FROM AUTHORS
WHERE UserRight & P_UserRight > 0
我們把儲存在列UserRight的值和傳入引數值P_UserRight進行 & 操作,來判斷滿足許可權的列。
Note:對於Enum列舉型別我們可以利用它的ToString方法和Parse方法
dim top as Toppings = Toppings.Pepperoni OR Toppings.Onions OR Toppings.Pineapple
Dim strTop as string = top.ToString()
strTop中儲存的值就是 “Pepperonii,Onions,Pineapple”
列舉的ToString方法返回一個列表,列表中包含所有相對應的值,值與值之間以逗號分隔;
Parse方法
Dim top2 as Toppings = CType([Enum].Parse(GetType(Toppings), "Onions,Pineapple"),Toppings)
原文地址: http://www.johnsample.com/articles/BitwiseEnums.aspx
btw:我不知道這篇文章應該放在哪個區,請dudu指導一下。