对枚举值(Enum)进行位操作(AND & OR)

    对枚举值进行AND OR 操作是 .Net 中最不常用的功能之一,在读了本文之后你将会发觉它其实也是一个比较有用的功能。

在做项目的时候我们可能经常会碰到这样一种情况:我们需要存储一些boolean值,然后在我们定义的类里面对应的添加一个Isxxxx 属性。比如说用户权限对象(IsAdminIsUserIsPowerUser等)。创建和检查这样的一些相关属性,然后还要注意这些属性之间的组合,随着这样的属性数量的增加,我们会发觉编写和维护代码的工作量会相当的大而且容易出错。

对于以上情况位操作(ANDOR)就可以相当轻松的进行处理,注意ANDOR是位操作符,他们是在数字的二进制表示层上进行操作。

如果你对二进制数不熟悉,请先参考相关资料。

二进制数上的操作有很多种,我们这里只需要用到ANDOR.

 

枚举类型(Enum)中的所有值都是整数,把一个整数用二进制进行表示的时候,我们可以把每一位都当作是一个boolean值,这样一个整数就可以来存储一个boolean值的列表。

为了可以方便的实现这个功能,我们规定在枚举对象当中存储的值只能够是2的幂。

下面我们举个例子,我们定义一个枚举对象来决定到底把什么调料放在Pizza上面。

< Flags() > Public Enum Toppings ‘注意需要Flags标记 表明是位编码

     None = 0      '务必定义一个等于0的枚举值

     Pepperoni = 1

     Mushrooms = 2

     Onions    = 4

     Anchovies = 8

     Peppers   = 16

     Pineapple = 32

End Enum

 

然后我们创建一个MakePizza的方法,它的输入参数是 Toppings枚举值

MakePizza(UseToppings as Toppings)

 

MakePizza方法内部我们首先定义一个枚举变量(MyToppings,对所有我们需要的值进行OR操作,然后赋值给它。

Dim MyToppings as Toppings
 MyToppings = Mushrooms OR Onions OR Peppers

 

现在存储在MyToppings中的值是22.

00000010 (Mushrooms - 2)

00000100 (Onions - 4)

00010000 (Peppers - 16)

--------―― OR

00010110 (22)

 

MakePizza(UseToppings as Toppings)方法内部,我们需要判断到底是什么值产生了MyToppings22)。

为了实现这个目的,我们把MyToppings与传入的UseTopping进行AND操作。任何非零的操作结果代表一个True值。

现在我们来测试一下,如果传入Pepperoni

If UseToppings AND Toppings.Pepperoni Then

 '添加 pepperonis

End If

 

操作结果是 0false

00010110 (UseToppings - 22)

00000001 (Pepperoni - 1)

-------- AND

00000000 (0)

如果传入Onions

结果是true(大于0

 

00010110 (UseToppings - 22)

00000100 (Onions - 4)

-------- AND

00000100 (4)

 

通过这样的方法,我们可以节省了存储我们要表示的对象的存储空间(在数据库当中或者内存当中)

我们不用创建Pepperoni, Onions, Mushrooms等的true/false列,只要存储一个数字22就可以了

 

通过这个例子,大家可以举一反三,比如说应用在用户权限上面(Edit, ReadOnly, Admin等)

你可以创建一个用户权限的枚举,然后把他们存储在数据库的一列上就可以了。

 

我们还可以在sql语句内部充分利用这个方便性,比如说

SELECT * FROM AUTHORS

WHERE UserRight & P_UserRight > 0

我们把存储在列UserRight的值和传入参数值 P_UserRight进行 & 操作,来判断满足权限的列。

 

Note:对于Enum枚举类型我们可以利用它的ToString 方法和Parse方法

 

dim top as Toppings = Toppings.Pepperoni OR Toppings.Onions OR Toppings.Pineapple

Dim strTop as string = top.ToString()

 

strTop中存储的值就是 “Pepperonii,Onions,Pineapple”

枚举的ToString方法返回一个列表,列表中包含所有相对应的值,值与值之间以逗号分隔;

 

Parse方法

Dim top2 as Toppings = CType([Enum].Parse(GetType(Toppings), "Onions,Pineapple"),Toppings)

posted @ 2011-07-05 17:13  年轻的蜗牛  阅读(1250)  评论(0编辑  收藏  举报