.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. (转)redux

    随着 JavaScript 单页应用开发日趋复杂,越来越多的 state (状态)需要在前端进行管理. 这些 state 可能包括服务器响应.缓存数据.本地生成尚未持久化到服务器的数据,也包括 UI ...

  2. Vmware安装Linux系统的vmware-tools

    我们应对都用vmware虚拟机,如果虚拟机是windows系统,每次虚拟机下方提示安装vmware-tools时,我们只需要点击安装即可. 但如果虚拟机安装的是linux系统的时候,发现就没一样了. ...

  3. mwArray与C++接口

    1.Matlab调用C++:http://blog.csdn.net/zouxy09/article/details/20553007 摘录下效果图: 2.mwArray类操作:http://blog ...

  4. Windows负载机JVM 远程监控Linux服务器下tomcat

    基本是跟着网上的操作进行的,除了遇到一个Local host name unknown的问题: 一.Linux服务器操作部分 服务器地址:10.64.111.68 首先配置JMX: 1.找到jdk目录 ...

  5. 优动漫PAINT动画创作功能介绍

    优动漫PAINT也就是我们常说的clip studio paint(CSP)的中文版本,它是一款功能强大的漫画.插画绘制软件,它搭载了绘制漫画和插画所需的所有功能,包括丰富的笔工具.超强的笔压感应和手 ...

  6. oracle AWR详解

    原文地址:https://blog.csdn.net/elvis_lfc/article/details/52326148 啥是AWR? =============================== ...

  7. 路飞学城Python-Day180

    部署作业 [pythonanywhere]

  8. 路飞学城Python-Day59(第五模块复习题)

    HTML div标签是块级标签,单独一行,可以作为其他标签的容器,没有特定含义 span是内联标签,可以作为文本内容的容器,没有特定含义 1. 查询一下对div和span标签的理解 不同的标签有自己含 ...

  9. HDU1527 - 取石子游戏【威佐夫博弈】

    有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后把石子全部取完者为胜者. ...

  10. BZOJ 2161 布娃娃 (主席树)

    题面 想了一个主席树做法 我们把每个区间的两个端点拆开 对$L,R$分别从小到大排序,分别从左到右依次把对应标号的$c_{i}$插入到权值主席树里 每次查询$p_{i}$,在排序后的$L,R$数组上分 ...