enum的做用不作描述,這是C#的基礎程序員
設置enum 很簡單,本文不作討論。數據庫
可是enum設置值有種特殊方式,如url
enum en { a=1, b=2, c=4, d=8, e=16, …… }
你會發現這個枚舉的值很是有規律,1,2,4,8,16,……,64,……1024。spa
其實質就是2^n 次方的值 。code
咱們再看下如下等式blog
10進制 | 2進制 |
1 | 00000001 |
2 | 00000010 |
4 | 00000100 |
8 | 00001000 |
16 | 00010000 |
觀察2進制那一列看看有什麼發現? 將這幾個數按位&一下會發現獲得了一個00011111 的數字,這樣說可能沒法理解。不過請繼續看下去v8
一般一個字節等於8位。 1byte=8bit ,做爲程序員常常能見到 byte[i] =0xFF;這樣的語句,那麼一個字節能存儲的最大值是多少呢? 255(無符號狀況下) ! 沒錯 0xff=+255 get
0xff=+255=11111111 ,因而有人說用這種方式一個枚舉能表達的最大值是255,即這樣的一個枚舉能夠有 8個值.it
再自誇觀察你會發如今en這個枚舉中b的值能夠包含a ,c的值能夠包含a,b ,a+b (1,2,3) 這三種狀況,d的值能夠包含,a,b,c,a+b ,a+c ,b+c ,a+b+c 這幾種狀況,是否是很是巧妙table
基於按位運算的這些特性,能夠很方便的使用 位運算符 來計算一個枚舉值是否包含了另一個枚舉值,這在權限系統中至關有用。
舉個例子:
限制數據庫中角色字段存儲了一個值是3,en這個枚舉中是沒有這個值的,那麼3 這個數據必定包含了多個en的枚舉值:1|2 。使用位運算獲得結果 1|2=3(0001|0010=0011),簡直太巧妙了
那麼是否是就能用一個字段來存儲多個權限了?!
既然這樣存儲了,那麼將數據拿出來後就須要有方法來判斷這個值是否包含了要對比的值了,方法以下: 使用&運算來確認
例如: var hasFlag =((3&(int)en.a)!=0); 就能夠判斷是否包含 a這個值了,運算過程: 0011&0001=0001; 這說明3中包含了en.a
下邊是C#中枚舉運算的其餘一些技巧
en e = (en) Enum.Parse(typeof(en), 3); //
檢查枚舉是否包含某個元素:
bool hasFlag = ((e& en.a) != 0); //這個運算中 e.a=00000001 那麼當e&e.a時候 1前邊的全變成了0
要從組合狀態中去掉一個元素
en e = en.a | en.b;
e1= e ^ en.a; //e1=en.b 了, 0011^0001=0010=2=en.b
若是執行一次 e1= e1 ^ en.a 則e1的值還原
e1=e //0010^0001=0011=3= en.a | en.b
當en加上[flags] 特性的狀況下
e.ToString()=" en.a,en.b "