c#中利用“|”运算组合多项
2014-01-16 13:53
260 查看
前几天看到一段代码
咋一看有些莫名奇妙,怎么传参的时候带了个或运算,其实这里面是有讲究的,查阅了各方资料,QQ群里赖着大牛问,才搞明白。这个运算可以用来进行多项组合。
举个例子,在设计权限的时候,你肯定会这样设计,权限A,做什么,权限B,做什么,权限C,做什么...如此定义权限,在调用处理函数时,我们直接传对应的权限Id就行,假设用户甲有A权限,我很明确得传权限A的Id,用户乙有B权限,我传B权限的Id,这样看来似乎是合理的。但是,如果用户丙同时有A权限和B权限怎么办呢,你可能会说,那我定义权限的时候定个AB’的权限好了,这样凡是同时有A和B权限的用户传AB’的Id就行了,我一开始也是这么想的,不过,这个做法是不推荐的,也是不巧妙的,假如还有用户同时有ABC权限,或者BC权限,或者CD权限,那么我就什么事也不用干了,就一直在给它定义类型了。
推荐的做法是,传参用“|”运算组合,处理用“&”运算拆分,这样,调用者可以随意组合,而对于处理者,则只定义最基本的单个处理“&”判断即可。看个例子:
定义一个枚举表示权限类型:
[align=left] 定义一个处理函数:[/align]
然后在其他地方调用:
[align=left] 你会看到每次调用都会精准得执行。为什么可以这样呢,看我定义的枚举,对应的值分别是[/align]
为什么我不定义成0x01,0x02,0x03,0x04,这是就依赖于我一开始讲的“|”和“&”运算了,“|”或运算是只要有1方为1就为1,“&”与运算是两者都为1才为1,把0x01,0x02,0x04,0x08转成2进制就是
任何两个组合,都会在自己的位上变为1。之后再拆分,由于之前组合过,自然就能精准地定位了。比如0x1和0x8组合,组合后就是1001,那么之后通过“&”来拆分,当&0x1时就能进去,&到0x8时也能进去,像这种0x01,0x02,0x04,0x08用行话讲叫“开关位”,今天在QQ群里问人被人说,哎~丢银啊~
[align=left] 如此,便能以不变应万变,组合出任意结果,真是很方便啊。[/align]
int i = GetCount(para1 | para2);
咋一看有些莫名奇妙,怎么传参的时候带了个或运算,其实这里面是有讲究的,查阅了各方资料,QQ群里赖着大牛问,才搞明白。这个运算可以用来进行多项组合。
举个例子,在设计权限的时候,你肯定会这样设计,权限A,做什么,权限B,做什么,权限C,做什么...如此定义权限,在调用处理函数时,我们直接传对应的权限Id就行,假设用户甲有A权限,我很明确得传权限A的Id,用户乙有B权限,我传B权限的Id,这样看来似乎是合理的。但是,如果用户丙同时有A权限和B权限怎么办呢,你可能会说,那我定义权限的时候定个AB’的权限好了,这样凡是同时有A和B权限的用户传AB’的Id就行了,我一开始也是这么想的,不过,这个做法是不推荐的,也是不巧妙的,假如还有用户同时有ABC权限,或者BC权限,或者CD权限,那么我就什么事也不用干了,就一直在给它定义类型了。
推荐的做法是,传参用“|”运算组合,处理用“&”运算拆分,这样,调用者可以随意组合,而对于处理者,则只定义最基本的单个处理“&”判断即可。看个例子:
定义一个枚举表示权限类型:
public enum Privilege { Read = 0x01, Write = 0x02, Add = 0x04, Delete = 0x08, }
[align=left] 定义一个处理函数:[/align]
public void GetPrivilege(Privilege pri) { if ((pri & Privilege.Read) == Privilege.Read) { //do something } if ((pri & Privilege.Write) == Privilege.Write) { //do something } if ((pri & Privilege.Add) == Privilege.Add) { //do something } if ((pri & Privilege.Delete) == Privilege.Delete) { //do something } }
然后在其他地方调用:
... GetPrivilege(Privilege.Read); GetPrivilege(Privilege.Write); GetPrivilege(Privilege.Add); GetPrivilege(Privilege.Delete); GetPrivilege(Privilege.Read | Privilege.Write); GetPrivilege(Privilege.Write | Privilege.Add); GetPrivilege(Privilege.Read | Privilege.Write | Privilege.Add); ...
[align=left] 你会看到每次调用都会精准得执行。为什么可以这样呢,看我定义的枚举,对应的值分别是[/align]
0x01 0x02 0x04 0x08
为什么我不定义成0x01,0x02,0x03,0x04,这是就依赖于我一开始讲的“|”和“&”运算了,“|”或运算是只要有1方为1就为1,“&”与运算是两者都为1才为1,把0x01,0x02,0x04,0x08转成2进制就是
0001 0010 0100 1000
任何两个组合,都会在自己的位上变为1。之后再拆分,由于之前组合过,自然就能精准地定位了。比如0x1和0x8组合,组合后就是1001,那么之后通过“&”来拆分,当&0x1时就能进去,&到0x8时也能进去,像这种0x01,0x02,0x04,0x08用行话讲叫“开关位”,今天在QQ群里问人被人说,哎~丢银啊~
[align=left] 如此,便能以不变应万变,组合出任意结果,真是很方便啊。[/align]
相关文章推荐
- c#中利用“|”运算组合多项
- 利用C#动态编译功能实现像Javascript中的Eval的功能来将一段字符串进行数学运算
- 利用位图方法求字符串的组合(类似于位运算模拟加法)
- 利用二进制数据的XOR(异或)运算进行加/解密(C#版)
- c#中利用简单枚举和标志枚举(组合,删除,查询是否包含)
- C#如何利用Stopwatch比较精确的测试算法运算时间
- 利用XOR运算进行简单加密(C# 3.0完全参考手册)
- c# 如何利用异或运算进行简单加密解密
- 在C#中对枚举进行位运算--枚举组合
- 利用dynamic类型对C#泛型参数运算
- 利用BPEL进行服务组合
- \t\t利用C#调用WINRAR实现压缩与解压
- java中float,double利用BigDecimal运算
- 位运算与组合搜索(一)
- C#利用WebClient 两种方式下载文件
- C#中byte类型运算
- 利用c#制作简单的留言板 (4)
- C#利用委托反射将DataTable转换为实体集
- 一般法求PI,以及利用超长数运算求长PI(总结)
- c#指针和寻址运算