在實(shí)際問(wèn)題中,有些變量的取值被限定在一個(gè)有限的范圍內(nèi)。例如,一個(gè)星期內(nèi)只有七天,一年只有十二個(gè)月,性別只有男跟女等等。如果把這些量說(shuō)明為整型、字符型或其它類型顯然是不妥當(dāng)?shù)?。為此,C#提供了一種稱為“枚舉”的類型。在“枚舉”類型的定義中列舉出所有可能的取值,被說(shuō)明為該“枚舉”類型的變量取值不能超過(guò)定義的范圍。應(yīng)該說(shuō)明的是,枚舉類型是一種基本數(shù)據(jù)類型,而不是一種構(gòu)造類型,因?yàn)樗荒茉俜纸鉃槿魏位绢愋汀?div style="height:15px;">
1、定義枚舉
定義枚舉很簡(jiǎn)單,直接使用enum關(guān)鍵字聲明即可,例如定義性別的枚舉,性別只有男和女
public enum Sex
{
女 = 0,//’0‘是’女‘對(duì)應(yīng)的內(nèi)部表示,也可以說(shuō)是女的Value,’女‘是外部表示,也可以說(shuō)是Name
男 = 1,
}
2.使用枚舉
代碼 1 public void UseEnum()
2 {
3 //獲取枚舉對(duì)應(yīng)的值
4 int enumValue = (int)Sex.男;//enumValue的值則為 1
5
6 //獲取枚舉的名稱
7 string enumText = Sex.男.ToString();//enumText的值則為 男
8
9 //將int類型值轉(zhuǎn)換為對(duì)應(yīng)的枚舉
10 int intValue = 1;//int值
11 Sex sex = (Sex)intValue;//sex則為對(duì)應(yīng)男的枚舉
12
13 //將名稱轉(zhuǎn)換為對(duì)應(yīng)的枚舉
14 string strValue = "男";
15 sex = (Sex)Enum.Parse(typeof(Sex), strValue);//sex則為對(duì)應(yīng)男的枚舉
16
17 //判斷int值或名稱是否在枚舉定義項(xiàng)類
18 if (Enum.IsDefined(typeof(Sex), intValue))//第二個(gè)參數(shù)也可以傳入strValue
19 {
20 //有
21 }
22
23 //switch來(lái)判斷sex (小技巧:先輸入switch 再加兩個(gè)Tab鍵 ,然后再switch()
24 //里面輸入枚舉,再回車鍵,代碼段就會(huì)自動(dòng)的將枚舉所有項(xiàng)加上case)
25 switch (sex)
26 {
27 case Sex.女:
28 break;
29 case Sex.男:
30 break;
31 default:
32 break;
33 }
34 //........................
35 }
3.通常我們?cè)跀?shù)據(jù)庫(kù)中,很多的一些狀態(tài)、類型、性別等等字段保存的是數(shù)字,但我們?cè)陂_(kāi)發(fā)時(shí)需要判斷這些狀態(tài)時(shí),直接使用 if(UserInfo.Sex==0)這種方式來(lái)判斷,顯然不太好,如果狀態(tài)多時(shí),自己都難分辨哪個(gè)數(shù)字代表什么狀態(tài)。并且代碼也不可觀,我們?cè)趯?xiě)代碼時(shí)應(yīng)該盡量少寫(xiě)硬代碼。如果使用枚舉定義,數(shù)據(jù)庫(kù)存儲(chǔ)的枚舉對(duì)應(yīng)的值,而在寫(xiě)代碼時(shí)使用枚舉的名稱,這樣一看代碼就知道數(shù)據(jù)庫(kù)儲(chǔ)值的是什么狀態(tài)。非常清楚明了。
4.UI層顯示枚舉的名稱。如果數(shù)據(jù)庫(kù)存儲(chǔ)的是枚舉的值(為數(shù)字),而在UI上當(dāng)然不能已數(shù)字的方式顯示,應(yīng)該顯示對(duì)應(yīng)的枚舉名稱。例如在一個(gè)用戶信息列表中需要綁定用戶性別(枚舉為上述的Sex),那該如何顯示枚舉的名稱呢?一下提供多種方式
3.1:GridView控件綁定數(shù)據(jù)源為例,可以添加一列模板項(xiàng),通過(guò)值獲取枚舉名稱
代碼 1 <asp:TemplateField HeaderText="性別">
2 <ItemTemplate>
3 <%#(枚舉所在命名空間.Sex)Convert.ToInt32(Eval("Sex"))%>
4 </ItemTemplate>
5</asp:TemplateField>
3.2: 通過(guò)Enum對(duì)象獲取名稱
代碼 1 <asp:TemplateField HeaderText="性別">
2 <ItemTemplate>
3 <%#Enum.GetName(typeof(枚舉所在命名空間.Sex), Convert.ToInt32(Eval("Sex")))%>
4 </ItemTemplate>
5 </asp:TemplateField>
還有很多方式來(lái)處理這個(gè)問(wèn)題,大家可以自由選擇。
5.枚舉的‘高級(jí)用法’組合運(yùn)用:例如一個(gè)界面里有:增、刪、查、改等操作,但對(duì)應(yīng)不同用戶就有不同操作權(quán)限。例如A用戶只能增、刪,而B(niǎo)用戶只能查、改等等。如果在權(quán)限表中某一個(gè)字段類型指定用戶的操作權(quán)限時(shí),問(wèn)題就出來(lái)了。來(lái)看看一下3種解決方式:
1.每個(gè)操作權(quán)限一條數(shù)據(jù),缺點(diǎn):每次更改權(quán)限時(shí),避免不了刪除和新增,并且數(shù)據(jù)量龐大,如果一個(gè)用戶有一千權(quán)限就代表有一千條數(shù)據(jù),那這張表的數(shù)據(jù)就不敢想象了。
2.一個(gè)字段存儲(chǔ)所有的操作權(quán)限,每個(gè)操作權(quán)限使用 某個(gè)指定的符號(hào)作為分隔符,這種方式叫簡(jiǎn)單、方便。
3.就是使用我們的枚舉組合,在一個(gè)字段存儲(chǔ)所有的操作權(quán)限,但值只為一個(gè)數(shù),不像方式2使用分隔符分開(kāi)。
當(dāng)然,還有很多方式可以解決這種問(wèn)題。我們現(xiàn)在就來(lái)看看如何使用枚舉組合來(lái)代表多個(gè)操作權(quán)限。
5.1:定義一個(gè)操作權(quán)限枚舉:
[Flags]//必須打上一個(gè)標(biāo)記,打上這個(gè)標(biāo)記系統(tǒng)才能識(shí)別這個(gè)枚舉可使用組合方式
public enum Role
{
未分配=0,
刪除數(shù)據(jù) = 1,
修改數(shù)據(jù) = 2,
新增數(shù)據(jù) = 4,
查看數(shù)據(jù) = 8,
}
5.2:如果用戶有刪除、修改的權(quán)限在枚舉定義中只有1和2的枚舉,那怎么將這兩個(gè)枚舉值組合成一個(gè)枚舉值存儲(chǔ)到數(shù)據(jù)庫(kù)呢?很簡(jiǎn)單,看一下代碼:
int allRole = ((int)Role.刪除數(shù)據(jù)) + ((int)Role.修改數(shù)據(jù));
//這時(shí)allRole的值為3 (兩個(gè)枚舉對(duì)應(yīng)值相加:1+2=3),這時(shí)直接將allRole值存儲(chǔ)到數(shù)據(jù)就可以了
現(xiàn)在我們就來(lái)判斷用戶是否具有某個(gè)操作權(quán)限,先從數(shù)據(jù)庫(kù)中取出權(quán)限值,以上述,allRole則為數(shù)據(jù)庫(kù)中取出的值,為3,接下來(lái)我們通過(guò)位算符來(lái)判斷:
代碼 Role myAllRole = (Role)allRole;//將int值強(qiáng)制轉(zhuǎn)換為枚舉
//此時(shí),myAllRole的名稱為 ‘ 刪除數(shù)據(jù), 修改數(shù)據(jù) ’ ,值為3
//判斷是否有刪除權(quán)限
if ((myAllRole & Role.刪除數(shù)據(jù)) == Role.刪除數(shù)據(jù))
{
//有
}
注意此處使用了 位算符& 方式來(lái)獲取判斷,關(guān)于位算符的使用在此就不講了。組合運(yùn)用大概就是這樣。必須注意的地方就是枚舉值的定義,我們可以看到Role枚舉的定義值的規(guī)律,0到1,1到2,2到4,4到8,8到16......當(dāng)前的值為上個(gè)值的2次方,為什么要這樣定義呢?是因?yàn)槿魏蔚慕M合都可以在枚舉范圍中某幾個(gè)值的總和,例如組合值為15,那15就等于枚舉定義范圍里的定義值為1、2、4、8相加,15=1+2+4+8。只有按規(guī)律定義值,就可以組合成任意數(shù)。
組合必須注意的幾點(diǎn):
1.枚舉定義時(shí),必須打上[Flags]標(biāo)記,系統(tǒng)才會(huì)根據(jù)這個(gè)標(biāo)記來(lái)決定這個(gè)枚舉是否可組合使用
2.定義枚舉的值必須按以上所說(shuō)的規(guī)律定義,例如:0、1、2、4、8、16、32.......也可以使用3次方的方式,例如:0、3、6、12、24..........
6.使用優(yōu)點(diǎn)總結(jié)
1.規(guī)則性:例如數(shù)據(jù)庫(kù)某個(gè)字段的值只在1、2、3、4,例如狀態(tài),當(dāng)我們?cè)阡浫霐?shù)據(jù)時(shí),我們可以從枚舉中取值,這樣避免了這個(gè)字段出現(xiàn)其它值,同時(shí)也使代碼更容易理解,因?yàn)樵谌≈禃r(shí),我們是拿枚舉定義的名稱,名稱是我們自定義的易理解的中文或英文。
2.易解性:就是上述所說(shuō)的,枚舉名稱是用中文和英文來(lái)定義,在使用時(shí),則拿枚舉的名稱,這樣一看代碼就知道。而不會(huì)在代碼中寫(xiě)1、2、3、4這樣的數(shù)字,也許過(guò)段時(shí)間自己寫(xiě)的都忘了了1代表什么?2代表什么?了,更何況日后他人的維護(hù)呢。