c# 二进制或算法实现枚举的HasFlag函数
在权限的管理中,常常会出现一个权限包含的现象。例如,有三种基本权限:职员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, }
15.6.6补充:
用linq to ef做hasflag查询时,做了一个测试,结果很有趣:
var f1 = db.Where(x => !x.Status.HasFlag(FlagEnum.Deleted)); var f2 = db.Where(x => ((int)x.Status & (int)FlagEnum.Deleted) != (int)FlagEnum.Deleted); var f3 = db.Where(x => x.Status.HasFlag(FlagEnum.Deleted)); var f4 = db.Where(x => ((int)x.Status & (int)FlagEnum.Deleted) == (int)FlagEnum.Deleted);
对应的sql语句的where条件是:
f1
WHERE NOT (((( CAST( [Extent1].[Status] AS int)) & ( CAST( 4 AS int))) = CAST( 4 AS int)) AND ((CASE WHEN (( CAST( [Extent1].[Status] AS int)) & ( CAST( 4 AS int)) IS NULL) THEN cast(1 as bit) ELSE cast(0 as bit) END) = 0))
f2
WHERE NOT ((4 = (( CAST( [Extent1].[Status] AS int)) & (4))) AND (( CAST( [Extent1].[Status] AS int)) & (4) IS NOT NULL))
f3
WHERE (( CAST( [Extent1].[Status] AS int)) & ( CAST( 4 AS int))) = CAST( 4 AS int)
f4
WHERE 4 = (( CAST( [Extent1].[Status] AS int)) & (4))}
直接说明了HasFlag和source & target = target的关系。
欢迎纠正和补充。转载请注明出处:http://www.cnblogs.com/icyJ/
转载于:https://www.cnblogs.com/icyJ/archive/2013/02/20/HasFlag.html
c# 二进制或算法实现枚举的HasFlag函数相关推荐
- OPJ2.1基本算法之枚举1815:画家问题
OPJ2.1基本算法之枚举 1815:画家问题 题目传送门 描述 有一个正方形的墙,由N*N个正方形的砖组成,其中一些砖是白色的,另外一些砖是黄色的.Bob是个画家,想把全部的砖都涂成黄色.但他的画笔 ...
- 1.Python算法之枚举算法
1.什么是枚举算法? 枚举算法也叫穷举算法,最大特点是在面对任何情况时会尝试每一种解决方法.在进行归纳推力时,如果逐个考察了某类事件的所有可能情况,因而得出一般结论,那么这个结论是可靠的,这种归纳方 ...
- JavaScript实现floatAsBinaryString浮点转为二进制字符串算法(附完整源码)
JavaScript实现floatAsBinaryString浮点转为二进制字符串算法(附完整源码) floatAsBinaryString.js完整源代码 floatAsBinaryString.j ...
- 2.1基本算法之枚举_1812完美立方
http://noi.openjudge.cn/ch0201/1812/ C++代码来源于以下链接 https://blog.csdn.net/qq_26919935/article/details/ ...
- Openjudge_ 2.1基本算法之枚举_1809 两倍 C++ scratch
http://noi.openjudge.cn/ch0201/solution/21246662/ /* Openjudge_ 2.1基本算法之枚举_1809 两倍 http://noi.openju ...
- 2.1基本算法之枚举_1749数字方格
http://noi.openjudge.cn/ch0201/1749/ /* 2.1基本算法之枚举_1749数字方格01 http://noi.openjudge.cn/ch0201/1749/ht ...
- 【0-1背包】二进制灰狼算法解决0-1背包问题【Matlab】
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一.0-1背包问题 1.问题描述 2.数学模型 二 .二进制灰狼算法 1.引言 2.算法改进 3.数学模型 4.算法流程 三 ...
- OPJ2.1基本算法之枚举7217:猴子吃桃
OPJ2.1基本算法之枚举&&7217:猴子吃桃 题目传送门 思路:就是一个脑筋急转弯--(话说这一章有好多脑筋急转弯问题--) 因为每次分的时候,都会多出来一个,对于N个猴子,如果给 ...
- OPJ 2.1基本算法之枚举:熄灯问题
OPJ 2.1基本算法之枚举 1813:熄灯问题 题目传送门 个人认为这是这一章为数不多不水的题之一--可能是我太弱了 思路: 既然这道题是枚举"算法"里的,那肯定就是要枚举.那么 ...
最新文章
- 衡量计算机的平均无故障时间6,平均无故障时间MTBF测试及计算过程
- kotlin访问控制符可见性
- java构造函数_JAVA的构造函数是怎么写的。万分感谢。路过的请不要嘲笑%_%
- 数论 —— 斐波那契数列(Fibonacci)
- JS中的立即执行函数
- ‘utf-8‘ codec can‘t decode byte 0xb8 in position 0: invalid start byte
- 东大OJ-1391-Big big Power
- Lua中ipairs和pairs的区别详解
- 因为马云,这也许是他们过得最有意思的腊八节
- android 时间水印相机,水印相机时间打卡
- Git遇到的问题:This is not a valid source path/URL
- 如何用RIGOL任意函数发生器产生任意波形
- matlab 光平面标定代码,光平面标定法
- 最小生成树的第三种求法-Borůvka (Sollin) 算法
- QT 调试时出现 Unable to create a debugging engine.
- Linux 文件后面带星号
- 硅谷的政治泡沫:反对特朗普,与美国大部分地区观念出现割裂
- js获取时间,根据时间生成数字
- 使用ANSI控制字体颜色
- 基于DYDX闪电贷在Cofix和Uniswap之间套利