c# 二进制或算法实现枚举的HasFlag函数

from:http://www.cnblogs.com/icyJ/archive/2013/02/20/HasFlag.html

 

 

在权限的管理中,常常会出现一个权限包含的现象。例如,有三种基本权限:职员A、职员B、职员C.在此基础上,有经理权限,它包括A和B两种权限;还有老板权限,包含A/B/C三种权限。

 

在代码中,我们可以用枚举来管理这些权限。

[Flags]
public  enum EnumHasFlag
{
    A =  1 <<  0,
    B =  1 <<  1,
    C =  1 <<  2,
    Manager = A | B,
    Boss = A | B | C,
}

这段代码的特点是,定义枚举是用了一个属性来限制[Flags],以及每个值都是用二进制递增来赋值。这样做的好处是,可以通过枚举的HasFlag函数来判断某一个权限是否包含另一个权限。

static  void Main( string[] args)
{
     var rightA = EnumHasFlag.Boss;
     var rightB = EnumHasFlag.Manager;
     if (rightA.HasFlag(EnumHasFlag.C)) Console.WriteLine( " rightA can do this ");
     if (rightB.HasFlag(EnumHasFlag.C)) Console.WriteLine( " rightB can do this ");
    Console.ReadKey();
}

最终代码会输出:rightA can do this。这样,通过HasFlag就可以判断枚举值的包含关系,从而进行相应的权限指定和管理。

这样的效果,还可以用过二进制的或运算来实现。基本语句是source | target == source.某个数值A,与另一个数值B进行或运算之后的结果还是A的话,可以判断A包含B。

static void Main(string[] args) {     
var A = 1 << 0 | 1 << 1;     
if ((A | (1 << 0)) == A) 
Console.WriteLine("A has 1<<0");     
if ((A | (1 << 2)) != A) 
Console.WriteLine("A doesn't have 1<<2"); }

代码的输出结果为:

A has 1<<0  

A doesn't have 1<<2

在了解逻辑的前提下,我们可以做如下的开关:

static  void Main( string[] args)
{
    ControlCenter( 1 <<  0 |  1 <<  3);
}

static  void ControlCenter( int input)
{
     if ((input | ( 1 <<  0)) == input) Console.WriteLine( " Do 0 ");
     if ((input | ( 1 <<  1)) == input) Console.WriteLine( " Do 1 ");
     if ((input | ( 1 <<  2)) == input) Console.WriteLine( " Do 2 ");
}

最终的输出结果可以自己下去测试一下。

本篇用两种方法来实现数值的包含关系管理。仔细的理解了实现的逻辑之后,可以用在很多地方。例如,我们可以将多个设置的是否值揉合成一个字段。形如'10111101',用最少的代码来管理这些设置信息。在选项很少而且对象的活动领域很小的情况下,可以考虑用二进制的或运算来实现。这样实现的优点是,可以不用单独建立枚举,代码量少很多;缺点是,代码的可读性差,调用灵活度也不如枚举的HasFlag,可扩展性也不强。

补充。下面有园友提出了source & target == target的判断算法,来判断source是否包含target。我觉得条件非常充分,而且整个思路比或运算更加清晰。后来查阅了其他的资料,发现对枚举中的1,2,4,8的理解,很多都是从这个算式出发。

 
  
static  void Main( string[] args)
{
     var xx = TestEnum.Manager;
     if ((xx & TestEnum.A) == TestEnum.A) Console.WriteLine( " Has A ");
    Console.ReadKey();
}

enum TestEnum
{
    A =  1 <<  0,
    B =  1 <<  1,
    C =  1 <<  2,
    Manager = A | B,
    Boss = A | B | C,
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值