enum的应用及flags特性

 enum的作用不做描述,这是C#的基础

设置enum 很简单,本文不做讨论。

但是enum设置值有种特殊方式,如

 enum en
    {
        a=1,
        b=2,
        c=4,
        d=8,
        e=16,
        ……
    }

你会发现这个枚举的值非常有规律,1,2,4,8,16,……,64,……1024。

其实质就是2^n 次方的值 。

我们再看下以下等式

10进制 2进制
1 00000001
2 00000010
4 00000100
8 00001000
16 00010000

观察2进制那一列看看有什么发现? 将这几个数按位&一下会发现得到了一个00011111 的数字,这样说可能无法理解。不过请继续看下去

通常一个字节等于8位。 1byte=8bit ,作为程序员经常能见到 byte[i] =0xFF;这样的语句,那么一个字节能存储的最大值是多少呢? 255(无符号情况下) ! 没错 0xff=+255 

0xff=+255=11111111  ,于是有人说用这种方式一个枚举能表达的最大值是255,即这样的一个枚举可以有 8个值.

再自诩观察你会发现在en这个枚举中b的值可以包含a ,c的值可以包含a,b ,a+b  (1,2,3) 这三种情况,d的值可以包含,a,b,c,a+b ,a+c ,b+c ,a+b+c 这几种情况,是不是非常巧妙

基于按位运算的这些特性,可以很方便的使用 位运算符 来计算一个枚举值是否包含了另外一个枚举值,这在权限系统中相当有用。

举个例子:

限制数据库中角色字段存储了一个值是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 "


 

原文地址:https://www.cnblogs.com/netqq/p/9383144.html