.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) 可以方便去掉一个元素。

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. 关于 Visual Studio 中文提示的问题

    [转自 https://blog.csdn.net/iloli/article/details/51055299] [转自 http://www.cnblogs.com/hellowin/p/6383 ...

  2. C# WebAPI小记

    新建WebAPI项目 新建一个Model 安装Entity Framework 添加连接字符串 去Web.config 中 <configuration> 节点中最下面添加 在Word中编 ...

  3. jquery分页点击后页面置顶

    前台: <a href="#" ><span id='top'></span></a> js中: 放在分页事件后,数据加载完成后 j ...

  4. 服务端 | Linux 学习总结 (一)

    http://billie66.github.io/TLCL/book/ 1.Ubuntu && linux shell 命令 Ubuntu两个重要版本:12.04和14.04 在终端 ...

  5. 3DSMAX制作逼真的欧式沙发建模教程

    这篇教程是朋友们介绍利用3DSMAX制作逼真的欧式沙发建模,教程制作出来的效果真心很不错,通过这篇教程,大家可以学习沙发建模的制作方法和思路,推荐过来,一起来学习吧! 3DSMAX软件下载:http: ...

  6. 第十三章 Python并发编程

    并发编程之多进程 python中如果想要充分的利用多核CPU的资源,大部分情况需要使用多进程,python提供了multiprocessing multiprocessing模块用来开启子进程,并在子 ...

  7. css——overflow

    Overflow:属性规定当前内容溢出元素框时发生的事情 1.当内容过多,元素框溢出 1)hidden:隐藏超出部分(overflow: hidden;) 2)auto:有下拉滚动条(overflow ...

  8. node——underscore的使用

    我在做新闻页面时,需要将之前存好点的data.json里的数据显示在首页上,而首页的每条新闻数据不能直接写定在上面,所以我们要将data里面的数据传递进去.我们需要使用underscore的templ ...

  9. python学习(一):python基础

    python两种执行方式: python解释器:py文件路径 python进入解释器:实时输入并获取执行结果 解释器路径: 在linux系统中,python文件在头部加上#!/usr/bin/env ...

  10. vue懒加载

    vue懒加载(白屏或者加载慢的解决方法) 懒加载:也叫延迟加载,即在需要的时候进行加载,随用随载. 为什么需要懒加载? 像vue这种单页面应用,如果没有应用懒加载,运用webpack打包后的文件将会异 ...