在实际问题中,有些变量的取值被限定在一个有限的范围内。例如,一个星期内只有七天,一年只有十二个月,性别只有男跟女等等。如果把这些量说明为整型、字符型或其它类型显然是不妥当的。为此,C#提供了一种称为“枚举”的类型。在“枚举”类型的定义中列举出所有可能的取值,被说明为该“枚举”类型的变量取值不能超过定义的范围。应该说明的是,枚举类型是一种基本数据类型,而不是一种构造类型,因为它不能再分解为任何基本类型。

1、定义枚举

    定义枚举很简单,直接使用enum关键字声明即可,例如定义性别的枚举,性别只有男和女




public 
     
   enum 
    Sex
 {
 女  
   = 
     
   0 
   ,//’0‘是’女‘对应的内部表示,也可以说是女的Value,’女‘是外部表示,也可以说是Name
 男  
   = 
     
   1 
   ,
 }

2.使用枚举




xlua中的枚举_xlua中的枚举

xlua中的枚举_c#_02

代码

1       
    public 
      
    void 
     UseEnum()
      2 
     {
      3 
      
    // 
    获取枚举对应的值 
    
      4 
      
      
    int 
     enumValue  
    = 
     ( 
    int 
    )Sex.男; 
    // 
    enumValue的值则为 1
      5 
    
      6 
      
    // 
    获取枚举的名称 
    
      7 
      
      
    string 
     enumText  
    = 
     Sex.男.ToString(); 
    // 
    enumText的值则为 男
      8 
    
      9 
      
    // 
    将int类型值转换为对应的枚举 
    
     10 
      
      
    int 
     intValue  
    = 
      
    1 
    ; 
    // 
    int值 
    
     11 
      
     Sex sex  
    = 
     (Sex)intValue; 
    // 
    sex则为对应男的枚举
     12 
    
     13 
      
    // 
    将名称转换为对应的枚举 
    
     14 
      
      
    string 
     strValue  
    = 
      
    " 
    男 
    " 
    ;
     15 
     sex  
    = 
     (Sex)Enum.Parse( 
    typeof 
    (Sex), strValue); 
    // 
    sex则为对应男的枚举
     16 
    
     17 
      
    // 
    判断int值或名称是否在枚举定义项类 
    
     18 
      
      
    if 
     (Enum.IsDefined( 
    typeof 
    (Sex), intValue)) 
    // 
    第二个参数也可以传入strValue 
    
     19 
      
     {
     20 
      
    // 
    有 
    
     21 
      
     }
     22 
    
     23 
      
    // 
    switch来判断sex (小技巧:先输入switch 再加两个Tab键 ,然后再switch()
     24 
      
    // 
    里面输入枚举,再回车键,代码段就会自动的将枚举所有项加上case) 
    
     25 
      
      
    switch 
     (sex)
     26 
     {
     27 
      
    case 
     Sex.女:
     28 
      
    break 
    ;
     29 
      
    case 
     Sex.男:
     30 
      
    break 
    ;
     31 
      
    default 
    :
     32 
      
    break 
    ;
     33 
     }
     34 
      
    // 
    ........................ 
    
     35 
      
     }


3.通常我们在数据库中,很多的一些状态、类型、性别等等字段保存的是数字,但我们在开发时需要判断这些状态时,直接使用 if(UserInfo.Sex==0)这种方式来判断,显然不太好,如果状态多时,自己都难分辨哪个数字代表什么状态。并且代码也不可观,我们在写代码时应该尽量少写硬代码。如果使用枚举定义,数据库存储的枚举对应的值,而在写代码时使用枚举的名称,这样一看代码就知道数据库储值的是什么状态。非常清楚明了。

4.UI层显示枚举的名称。如果数据库存储的是枚举的值(为数字),而在UI上当然不能已数字的方式显示,应该显示对应的枚举名称。例如在一个用户信息列表中需要绑定用户性别(枚举为上述的Sex),那该如何显示枚举的名称呢?一下提供多种方式

  3.1:GridView控件绑定数据源为例,可以添加一列模板项,通过值获取枚举名称


xlua中的枚举_xlua中的枚举

xlua中的枚举_c#_02

代码

1     <     asp:TemplateField HeaderText 
    = 
    " 
    性别 
    " 
    > 
         2       
    < 
    ItemTemplate 
    > 
         3       
    <% 
    #(枚举所在命名空间.Sex)Convert.ToInt32(Eval( 
    "Sex 
    " 
    ) 
    ) 
    %> 
         4       
    </ 
    ItemTemplate 
    > 
         5     </ 
    asp:TemplateField 
    >
  
  3.2:  通过Enum对象获取名称
     
代码       
1           <     asp:TemplateField HeaderText 
    = 
    " 
    性别 
    " 
    > 
         2           < 
    ItemTemplate 
    > 
         3      <%#Enum.GetName(typeof(枚举所在命名空间.Sex), Convert.ToInt32(Eval("Sex")))%>          4           </ 
    ItemTemplate 
    > 
         5           </ 
    asp:TemplateField 
    >


       还有很多方式来处理这个问题,大家可以自由选择。

5.枚举的‘高级用法’组合运用:例如一个界面里有:增、删、查、改等操作,但对应不同用户就有不同操作权限。例如A用户只能增、删,而B用户只能查、改等等。如果在权限表中某一个字段类型指定用户的操作权限时,问题就出来了。来看看一下3种解决方式:

  1.每个操作权限一条数据,缺点:每次更改权限时,避免不了删除和新增,并且数据量庞大,如果一个用户有一千权限就代表有一千条数据,那这张表的数据就不敢想象了。

  2.一个字段存储所有的操作权限,每个操作权限使用 某个指定的符号作为分隔符,这种方式叫简单、方便。

  3.就是使用我们的枚举组合,在一个字段存储所有的操作权限,但值只为一个数,不像方式2使用分隔符分开。

当然,还有很多方式可以解决这种问题。我们现在就来看看如何使用枚举组合来代表多个操作权限。

  5.1:定义一个操作权限枚举:

 


[Flags]    //    必须打上一个标记,打上这个标记系统才能识别这个枚举可使用组合方式    
         public      
   enum 
    Role
 {
        未分配=0,
 删除数据     =         1 
   ,
 修改数据     =         2 
   ,
 新增数据     =         4 
   ,
 查看数据     =         8 
   ,
 }


  5.2:如果用户有删除、修改的权限在枚举定义中只有1和2的枚举,那怎么将这两个枚举值组合成一个枚举值存储到数据库呢?很简单,看一下代码:

 

 


int     allRole     =     (( 
   int 
   )Role.删除数据)  
   + 
    (( 
   int 
   )Role.修改数据);
    //    这时allRole的值为3 (两个枚举对应值相加:1+2=3),这时直接将allRole值存储到数据就可以了


现在我们就来判断用户是否具有某个操作权限,先从数据库中取出权限值,以上述,allRole则为数据库中取出的值,为3,接下来我们通过位算符来判断:

 


xlua中的枚举_xlua中的枚举

xlua中的枚举_c#_02

代码

Role myAllRole      =      (Role)allRole;     //     将int值强制转换为枚举
     //     此时,myAllRole的名称为 ‘ 删除数据, 修改数据 ’ ,值为3
     //     判断是否有删除权限     
           if      ((myAllRole      & 
     Role.删除数据)  
    == 
     Role.删除数据)
 {
     //     有     
      }


 

注意此处使用了 位算符& 方式来获取判断,关于位算符的使用在此就不讲了。组合运用大概就是这样。必须注意的地方就是枚举值的定义,我们可以看到Role枚举的定义值的规律,0到1,1到2,2到4,4到8,8到16......当前的值为上个值的2次方,为什么要这样定义呢?是因为任何的组合都可以在枚举范围中某几个值的总和,例如组合值为15,那15就等于枚举定义范围里的定义值为1、2、4、8相加,15=1+2+4+8。只有按规律定义值,就可以组合成任意数。

组合必须注意的几点:

1.枚举定义时,必须打上[Flags]标记,系统才会根据这个标记来决定这个枚举是否可组合使用

2.定义枚举的值必须按以上所说的规律定义,例如:0、1、2、4、8、16、32.......也可以使用3次方的方式,例如:0、3、6、12、24..........

 

6.使用优点总结

  1.规则性:例如数据库某个字段的值只在1、2、3、4,例如状态,当我们在录入数据时,我们可以从枚举中取值,这样避免了这个字段出现其它值,同时也使代码更容易理解,因为在取值时,我们是拿枚举定义的名称,名称是我们自定义的易理解的中文或英文。

  2.易解性:就是上述所说的,枚举名称是用中文和英文来定义,在使用时,则拿枚举的名称,这样一看代码就知道。而不会在代码中写1、2、3、4这样的数字,也许过段时间自己写的都忘了了1代表什么?2代表什么?了,更何况日后他人的维护呢。