.NET中的枚举我们一般有两种用法,一是表示唯一的元素序列,例如一周里的各天;还有就是用来表示多种复合的状态。这个时候一般需要为枚举加上[Flags]特性标记为位域,例如:

[Flags]  
enum Styles{  
ShowBorder = 1,         //是否显示边框 
ShowCaption = 2,        //是否显示标题 
ShowToolbox = 4         //是否显示工具箱 
}  

这样我们就可以用"或"运算符组合多个状态,例如

myControl.Style = Styles.ShowBorder | Styles.ShowCaption;  

这时myControl.Style枚举的值将变成 1+2=3,它的ToString()将变成"Styles.ShowBorder , Styles.ShowCaption" 
这里我们可以解释为什么第三个值ShowToolbox可以为4,5..而不能为3。也就是说它的值不应该是前几项值的复合值。有一个比较简单的方法就是用2的n次方来依次为每一项赋值,例如 1,2,4,8,16,32,64.....

现在举个常见的Flags应用例子。例如一个简单的权限系统,有"Admin"和"User"两种角色,我们可以在表中放一个varchar()字 段,以文本形式存放权限字"Admin,User"。但是用Flags型枚举的话,我们就可以直接将 Roles.Admin | Roles.User 的值放在一个int字段里。

  

以下是关于枚举的一些常见操作: 
  

将枚举的值变回枚举对象: 
  Styles style = (Styles) Enum.Parse(typeof(Styles), 4 );    // -> style = Styles.Toolbox; 
  

检查枚举是否包含某个元素: 
  bool hasFlag = ((style & Styles.ShowBorder) != 0);

  其实我们还会碰到一种情况,就是需要从组合状态中去掉一个元素。用"^"运算符可以做到:

 Styles style = Styles.ShowBorder | Styles.ShowCaption;  
  style = style ^ Styles.ShowBorder;  

 这个时候style的值就会变成 Styles.ShowCaption

  但这里有一个很严重的问题(偶现在才发现) 
  我们这个时候再执行一次 
  style = style ^ Styles.ShowBorder; 
   按照我们的设想,这个时候 style 的值是 Styles.ShowCaption,不包含 Styles.ShowBorder,所以我们就算去掉这个元素,style应该还是不会变。但实际的 style 的值却又变成了 Styles.ShowBorder | Styles.ShowCaption !! 再执行一遍,又会去掉这个元素,周而复始。 
  当然我们可以在去掉某个元素前做一番检查,如果枚举包含这个元素,再去掉它:

if ((style & Styles.ShowBorder) != 0){  
    style = style ^ Styles.ShowBorder;  
}  

不知道有没有其它方法可以方便地从Flags枚举状态中去掉一个元素。。

  Thanks to mobilebilly: 
  style = style & (~Styles.ShowBorder) 可以方便去掉一个元素。

转自: https://www.cnblogs.com/lvdongjie/p/5577216.html

[转]C# 位域[flags]的更多相关文章

  1. C# 位域[flags] 转

    C# 位域[flags] .NET中的枚举我们一般有两种用法,一是表示唯一的元素序列,例如一周里的各天:还有就是用来表示多种复合的状态.这个时候一般需要为枚举加上[Flags]特性标记为位域,例如: ...

  2. C# 位域[flags]

    .NET中的枚举我们一般有两种用法,一是表示唯一的元素序列,例如一周里的各天:还有就是用来表示多种复合的状态.这个时候一般需要为枚举加上[Flags]特性标记为位域,例如: [Flags]   enu ...

  3. C# 特性(Attribute)之Flag特性

    本文参考自C# 位域[flags],纯属读书笔记,加深记忆 [Flags]的微软解释是“指示可以将枚举作为位域(即一组标志)处理.”其实就是在编写枚举类型时,上面附上Flags特性后,用该枚举变量是既 ...

  4. ahjesus C# Flags 位域略说

    class Program { [Flags] public enum Week { [Description("星期一")] Monday = << , [Descr ...

  5. c# 枚举基础有[flags]和没有的的区别

    枚举提供成组的常数值,它们有助于使成员成为强类型以及提高代码的可读性.在 C# 中,使用 enum 来声明枚举. 枚举分为简单枚举和标志枚举两种. 基本语法示例 enum Day { Sun, Mon ...

  6. c#中[Flags] 枚举类型定义问题_百度知道

    [Flags]的微软解释是“指示可以将枚举作为位域(即一组标志)处理.”其实就是在编写枚举类型时,上面附上Flags特性后,用该枚举变量是既可以象整数一样进行按位的“|”或者按位的“&”操作了 ...

  7. C#枚举中使用Flags特性

    .NET中的枚举我们一般有两种用法,一是表示唯一的元素序列:还有就是用来表示多种复合的状态.这个时候一般需要为枚举加上[Flags]特性标记为位域,这样我们就可以用"或"运算符组合 ...

  8. 处理“位域”枚举类型变量的几个例子

    所谓的位域就是说利用一个整形数字二进制下不同的标志位来使一个枚举变量可以记录多个信息. 例如现在有一个定义好的位域枚举: [Flags] public enum FlagEnum { 我是第一个=, ...

  9. 枚举类型与位域枚举Enum

    一.概述 定义一个值类型,其中包含固定值集合.枚举类型变量可以是此集合中的任意一个或多个值.枚举使用enum关键字来声明,与类同级.枚举本身可以有修饰符,但枚举的成员始终是公共的,不能有访问修饰符.枚 ...

随机推荐

  1. 【华科考研机试题】最长&最短文本

    题目 输入多行字符串,请按照原文本中的顺序输出其中最短和最长的字符串,如果最短和最长的字符串不止一个,请全部输出. 解题思路 1.输入所有字符串(有空格不另算字符串). 2.将char*字符串转换成s ...

  2. 树的问题小结(最小生成树、次小生成树、最小树形图、LCA、最小支配集、最小点覆盖、最大独立集)

    树的定义:连通无回路的无向图是一棵树. 有关树的问题: 1.最小生成树. 2.次小生成树. 3.有向图的最小树形图. 4.LCA(树上两点的最近公共祖先). 5.树的最小支配集.最小点覆盖.最大独立集 ...

  3. 读书笔记8-浪潮之巅(part3)

    浪潮之巅 ——风险投资 <浪潮之巅>的前半部分列举了在现代史上举足轻重的几家大型科技公司的历史,虽说成功的公司各有各的绝招,但是读多之后又略显重复.无聊(这不是说原书的内容.描述是无聊的, ...

  4. SQL Server-数据库架构和对象、定义数据完整性

    前言 本节我们继续SQL之旅,本节我们如题来讲讲一些基本知识以及需要注意的地方,若有不妥之处,还望指出,简短的内容,深入的理解,Always to review the basics. 数据库架构和对 ...

  5. Websphere 手动模拟删除应用操作

    Websphere  手动模拟删除应用操作 切记:不要在程序还在运行的时候,直接的remove掉应用程序,不然,会发生意外的错误.       最近,在项目中,不小心手动移除了正在运行的应用,发现se ...

  6. PCL:Ubuntu下安装配置PCL

    一:安装PCL 依据官网介绍:http://www.pointclouds.org/downloads/linux.html Ubuntu We currently support all Ubunt ...

  7. MindManager 2019新版上市 ,了解一下!

    所有的等待都是值得的!MindManager在蓄力一年后,给各位思维导图爱好者带来了全新的MindManager 2019 for Windows.全新的版本包含英语.德语.法语.俄语.中文.日语,新 ...

  8. Python基础:编码

    1:先说python2py2里默认编码是ascii文件开头那个编码声明是告诉解释这个代码的程序 以什么编码格式 把这段代码读入到内存,因为到了内存里,这段代码其实是以bytes二进制格式存的,不过即使 ...

  9. 数据分析例子-------CTR1

    1.CTR: (1)几个概念: impression(展示):用户看到该广告的次数.也就是一个广告被显示了多少次,它就计数多少.比如:打开网站的一个页面,网站上的所有广告就被显示了一次,每个广告增加1 ...

  10. C语言基础 (12) 文件的操作 FILE

    课程回顾 结构体基本操作: 结构体类型的定义 // struct为关键字 Stu为自定义标识符 // struct Stu才是结构体类型 // 结构体成员不能在定义类型时赋值 struct Stu { ...