C 位域 flags 列舉

2022-02-01 13:26:35 字數 1618 閱讀 4450

.net中的列舉我們一般有兩種用法,一是表示唯一的元素序列,例如一周裡的各天;還有就是用來表示多種復合的狀態。這個時候一般需要為列舉加上[flags]特性標記為位域,例如: 

[flags]  

enum

styles

這樣我們就可以用"或"運算子組合多個狀態,例如

mycontrol.style 

=styles.showborder 

|styles.showcaption;  

這時mycontrol.style列舉的值將變成 1+2=3,它的tostring()將變成"styles.showborder , styles.showcaption" 

這裡我們可以解釋為什麼第三個值showtoolbox可以為4,5..而不能為3。也就是說它的值不應該是前幾項值的復合值。有乙個比較簡單的方法就是用2的n次方來依次為每一項賦值,例如 1,2,4,8,16,32,64..... 

現在舉個常見的flags應用例子。例如乙個簡單的許可權系統,有"admin"和"user"兩種角色,我們可以在表中放乙個varchar()字段,以文字形式存放許可權字"admin,user"。但是用flags型列舉的話,我們就可以直接將 roles.admin | roles.user 的值放在乙個int欄位裡。 

以下是關於列舉的一些常見操作: 

將列舉的值變回列舉物件: 

styles style = (styles) enum.parse(typeof(styles), 4 );// -> style = styles.toolbox; 

檢查列舉是否包含某個元素: 

bool hasflag = ((style & styles.showborder) != 0);

其實我們還會碰到一種情況,就是需要從組合狀態中去掉乙個元素。用"^"運算子可以做到:

styles style 

=styles.showborder 

|styles.showcaption;  

style 

=style 

^styles.showborder; 

這個時候style的值就會變成 styles.showcaption 

但這裡有乙個很嚴重的問題(偶現在才發現

) 我們這個時候再執行一次 

style = style ^ styles.showborder; 

按照我們的設想,這個時候 style 的值是 styles.showcaption,不包含 styles.showborder,所以我們就算去掉這個元素,style應該還是不會變。但實際的 style 的值卻又變成了 styles.showborder | styles.showcaption !! 再執行一遍,又會去掉這個元素,周而復始。 

當然我們可以在去掉某個元素前做一番檢查,如果列舉包含這個元素,再去掉它:

if((style 

&styles.showborder) !=0

)不知道有沒有其它方法可以方便地從flags列舉狀態中去掉乙個元素。。 

thanks to mobilebilly: 

style = style & (~styles.showborder) 可以方便去掉乙個元素。

此文章轉於

enum flags 列舉Flags標示 位運算子

c 位運算 詳見 2012 04 23 10 26 06 分類 程式 net 舉報 字型大小訂閱 flags關鍵字允許我們在使用.net列舉變數時,使用多個組合值,多個值的賦值方法是使用關鍵字 即weekdays weekdays weekdays.monday weekdays.tuesday 判...

C 列舉中使用Flags特性

如果對乙個值可以包含多個,那麼可以使用列舉,加上flags 在寫前,需要知道一些基礎知識,取反 或 與,如果不知道的話,請去看看基礎。當然,這些太複雜了,我也不會在這裡解釋。假如有型別 flags public enum show 合併多個,使用 show show show.a show.b 乙個...

C 列舉中使用Flags特性

這種用處很大,比如許可權 執行狀態等,都可以用乙個int型儲存到資料庫中,c 中使用列舉可以處理這個問題。flags public enum permission c 對該型別的操作如下 permission permission permission.create permission.read ...