枚举类型表示组合状态的抽象代数原理
2014-05-12 13:48
246 查看
可以使用枚举类型定义位标志,从而使该枚举类型的实例可以存储枚举数列表中定义的值的任意组合。 (当然,某些组合在您的程序代码中可能没有意义或不允许使用。)
创建位标志枚举的方法是应用 System.FlagsAttribute 特性并适当定义一些值,以便可以对这些值执行 AND、OR、NOT 和 XOR 按位运算。 在位标志枚举中包含一个值为零(表示“未设置任何标志”)的命名常量。如果零值不表示“未设置任何标志”,则请不要为标志指定零值。
首先我们定义一个支持组合状态的枚举如下,用FlagsAttribute对定义的枚举类型进行标识:
FlagsAttribute标签的意义是按照位域来处理此枚举类型:
通常我们对组合的枚举类型的操作为:
1.检查组合中是否包含某个值 2.往组合中添加一个值 3.从组合中去掉某个值
我们定义上面三种操作如下:
x & y 整型按位“与”
x ^ y 整型按位“异或”
x | y 整型按位“或”
~x按位求反
RemovePermission 与 RemovePermission2 这两个方法需要说明一下,其中RemovePermission形式比较简单,一句代码搞定
对待删除的元素按位取反之后,按位与,直接表示保留除了toRemovePermission之外的其它所有权限。
RemovePermission2形式更加好理解,但是容易出错。如果没有第一句的判断直接异或操作的话可能会把原来没有的权限加进去。
数学原理:抽象代数之二进制码词群
设w=a1a2...an是一个n位二进制数码,称为一个码词,S是所有这样的码词构成的集合,即S={a1a2...an|ai=0或1,i=1,2,...n}
在S中定义二元运算|,表示位运算按位或
所以我们把原来的枚举类型换成数学符号如下
None=0000,Create=0001,Retrive=0010,Update=0100,Delete=1000,All=1111
由四位二进制数组成的二进制码集合为S={a1a2a3a4|ai=0或1},即所有的可能权限组合组成此集合。
对于我们定义的运算|,显然在此集合上满足封闭性,结合律,另外单位元为None=0000
同时所有元素的逆元也为None=0000。
所以集合S构成一个群(S,|),并且满足交换律,所以也是Abel群。
并且最小生成元集为M={None=0000,Create=0001,Retrive=0010,Update=0100,Delete=1000}
所以所有的权限组合均可以由M中的元素生成。
下面来分析下前面代码中的各种运算符的数学集合意义,a表示一个[b]二进制码词:[/b]
~: 表面上是求元素a的的按位求反,实际在集合中的意义是除去a元素的的其它所有元素的集合。
&: 按位与运算,在集合中的a&b的意义就是求a中的权限与b中权限的交集
^: 异或“^”运算相当于 a^b 相当于{权限x|x属于a,但x不属于b}U{权限y|y属于b,但不属于a}
|: 或运算“|”,在这里相当于是并运算,即集合得合并运算。
再回头看代码:
取得权限的交集,判断权限中是否包含verifiedPermission
添加权限,取集合的合并结果
删除一个权限,原权限集合与集合(~toRemovePermission)的交集,其中(~toRemovePermission)这个集合表示toRemovePermission的补集。
删除一个权限第二种方法.其中else之后的语句表示一个并集:{权限x|x属于compositePermission,但x不属于toRemovePermission}U{权限y|y属于toRemovePermission,但不属于compositePermission}
我们可以用枚举类型的此种用法实现程序中的状态组合,任务状态组合,权限管理组合等。
作者:Andy Zeng
欢迎任何形式的转载,但请务必注明出处。
/article/5796345.html
创建位标志枚举的方法是应用 System.FlagsAttribute 特性并适当定义一些值,以便可以对这些值执行 AND、OR、NOT 和 XOR 按位运算。 在位标志枚举中包含一个值为零(表示“未设置任何标志”)的命名常量。如果零值不表示“未设置任何标志”,则请不要为标志指定零值。
首先我们定义一个支持组合状态的枚举如下,用FlagsAttribute对定义的枚举类型进行标识:
[Flags] public enum Permission { None=0, Create=1, Retrive=2, Update=4, Delete=8, All=Create|Retrive|Update|Delete, }
FlagsAttribute标签的意义是按照位域来处理此枚举类型:
/// <summary>Indicates that an enumeration can be treated as a bit field; that is, a set of flags.</summary> /// <filterpriority>1</filterpriority> [AttributeUsage(AttributeTargets.Enum, Inherited = false), ComVisible(true)] [Serializable] public class FlagsAttribute : Attribute { }
通常我们对组合的枚举类型的操作为:
1.检查组合中是否包含某个值 2.往组合中添加一个值 3.从组合中去掉某个值
我们定义上面三种操作如下:
public static class PermissionExtention { public static bool HasPermission(this Permission compositePermission, Permission verifiedPermission) { return (compositePermission & verifiedPermission) == verifiedPermission; } public static Permission AddPermission(this Permission compositePermission, Permission toAddPermission) { if (compositePermission.HasPermission(toAddPermission)) return compositePermission; else return compositePermission | toAddPermission; } public static Permission RemovePermission(this Permission compositePermission, Permission toRemovePermission) { //if (!compositePermission.HasPermission(toAddPermission)) // return compositePermission; //else return compositePermission & (~toRemovePermission); } public static Permission RemovePermission2(this Permission compositePermission, Permission toRemovePermission) { if (!compositePermission.HasPermission(toRemovePermission)) return compositePermission; else return compositePermission^toRemovePermission; } }
我们注意到我们使用了全部四种操作符:& ,|,^,~来是想上面的三种目的。直观上理解三个操作符的意义就是
x & y 整型按位“与”
x ^ y 整型按位“异或”
x | y 整型按位“或”
~x按位求反
RemovePermission 与 RemovePermission2 这两个方法需要说明一下,其中RemovePermission形式比较简单,一句代码搞定
compositePermission & (~toRemovePermission);
对待删除的元素按位取反之后,按位与,直接表示保留除了toRemovePermission之外的其它所有权限。
RemovePermission2形式更加好理解,但是容易出错。如果没有第一句的判断直接异或操作的话可能会把原来没有的权限加进去。
数学原理:抽象代数之二进制码词群
设w=a1a2...an是一个n位二进制数码,称为一个码词,S是所有这样的码词构成的集合,即S={a1a2...an|ai=0或1,i=1,2,...n}
在S中定义二元运算|,表示位运算按位或
所以我们把原来的枚举类型换成数学符号如下
None=0000,Create=0001,Retrive=0010,Update=0100,Delete=1000,All=1111
由四位二进制数组成的二进制码集合为S={a1a2a3a4|ai=0或1},即所有的可能权限组合组成此集合。
对于我们定义的运算|,显然在此集合上满足封闭性,结合律,另外单位元为None=0000
同时所有元素的逆元也为None=0000。
所以集合S构成一个群(S,|),并且满足交换律,所以也是Abel群。
并且最小生成元集为M={None=0000,Create=0001,Retrive=0010,Update=0100,Delete=1000}
所以所有的权限组合均可以由M中的元素生成。
下面来分析下前面代码中的各种运算符的数学集合意义,a表示一个[b]二进制码词:[/b]
~: 表面上是求元素a的的按位求反,实际在集合中的意义是除去a元素的的其它所有元素的集合。
&: 按位与运算,在集合中的a&b的意义就是求a中的权限与b中权限的交集
^: 异或“^”运算相当于 a^b 相当于{权限x|x属于a,但x不属于b}U{权限y|y属于b,但不属于a}
|: 或运算“|”,在这里相当于是并运算,即集合得合并运算。
再回头看代码:
取得权限的交集,判断权限中是否包含verifiedPermission
public static bool HasPermission(this Permission compositePermission, Permission verifiedPermission) { return (compositePermission & verifiedPermission) == verifiedPermission; }
添加权限,取集合的合并结果
public static Permission AddPermission(this Permission compositePermission, Permission toAddPermission) { if (compositePermission.HasPermission(toAddPermission)) return compositePermission; else return compositePermission | toAddPermission; }
删除一个权限,原权限集合与集合(~toRemovePermission)的交集,其中(~toRemovePermission)这个集合表示toRemovePermission的补集。
public static Permission RemovePermission(this Permission compositePermission, Permission toRemovePermission) { //if (!compositePermission.HasPermission(toAddPermission)) // return compositePermission; //else return compositePermission & (~toRemovePermission); }
删除一个权限第二种方法.其中else之后的语句表示一个并集:{权限x|x属于compositePermission,但x不属于toRemovePermission}U{权限y|y属于toRemovePermission,但不属于compositePermission}
public static Permission RemovePermission2(this Permission compositePermission, Permission toRemovePermission) { if (!compositePermission.HasPermission(toRemovePermission)) return compositePermission; else return compositePermission^toRemovePermission; }
我们可以用枚举类型的此种用法实现程序中的状态组合,任务状态组合,权限管理组合等。
作者:Andy Zeng
欢迎任何形式的转载,但请务必注明出处。
/article/5796345.html
相关文章推荐
- 枚举类型原理
- System.ComponentModel.DataAnnotations表示与数据字段和参数关联的数据类型的枚举
- 第7章枚举类型输出5种球里去除3种不同球的组合
- 枚举类型在组合数据的使用
- c# (ENUM)枚举组合类型的谷歌序列化Protobuf
- 编程的有效方法--用枚举表示选项及状态
- 用"|" 表示多种状态的按位枚举
- Java枚举类型enum的原理
- 枚举类型入门用 Java 5.0 以类型安全的方式表示常量[摘]
- 枚举(enum)类型是Java 5新增的特性,它是一种新的类型,允许用常量来表示特定的数据片断,而且全部都以类型安全的形式来表示。
- SocketType 枚举----指定 Socket 类的实例表示的套接字的类型
- 对于数据库中表示状态或类型字段表示方法的思考
- 枚举类型入门 用 Java 5.0 以类型安全的方式表示常量
- iOS 高级开发技巧 1.熟悉Objective-C (五) 用枚举表示状态、选项、状态码
- JAVA进阶之旅(一)——增强for循环,基本数据类型的自动拆箱与装箱,享元设计模式,枚举的概述,枚举的应用,枚举的构造方法,枚举的抽象方法
- 使用SQL Server中按位于来表示组合状态
- 【2015/10/18】C学习日志_Day8 数据类型及其位表示,指针,内存状态
- SocketType 枚举----指定 Socket 类的实例表示的套接字的类型
- hdu 3935 -枚举+位运算表示状态和状态转移
- JAVA进阶之旅(一)——增强for循环,基本数据类型的自动拆箱与装箱,享元设计模式,枚举的概述,枚举的应用,枚举的构造方法,枚举的抽象方法