标志枚举

Posted 禅道

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了标志枚举相关的知识,希望对你有一定的参考价值。

public enum Emergency
{
    A = 1,
    B = 2,
    C = 4,
    D = 8
}
public class UnitTest1
{
    [Fact]
    public void Test1()
    {      
        var a = Emergency.A | Emergency.B;  //变量a为 3
        var b = Emergency.B | Emergency.D;  //变量b为10

        var aa = a.HasFlag(Emergency.A);//true ,a 包含枚举A
        var bb = a.HasFlag(Emergency.C);//false , a 不包含枚举C           
    }
}

我们发现定义的枚举都是2的指数,因为2的指数任意结合产生的结果值都不可能重复(不信自己试)。反过来,我们就可以根据结果值推算出包含的枚举。

为什么用位位运算符?位运算的四种结果:

0|0=0;  0|1=1;  1|0=1;  1|1=1;

也就是:

Emergency.A | Emergency.B| Emergency.B| Emergency.B;//不管怎么加都是 3 (如果使用 + 会一直累计)

为什么说任意结合合产生的结果值都不可能重复?

计算机只认识0和1。
下面我们对十进制和二进制做个对应:
 1  ->  0001
 2  ->  0010
 4  ->  0100
 8  ->  1000

这样我们更加形象的知道为什么2的指数结合不会有重复,且重复结合不累计。

一般用标记枚举我们都会在枚举上加一个Flags特性

[Flags]
public enum Emergency
{
    A = 1,
    B = 2,
    C = 4,
    D = 8
}
public class UnitTest1
{
    [Fact]
    public void Test1()
    {      
        var a = Emergency.A | Emergency.B;  //变量a为 A | B
        var b = Emergency.B | Emergency.D;  //变量b为 B | D
        var aa = a.ToString();//变量aa为 "A,B" 
        var bb = a & (~Emergency.A);//从组合状态中去掉一个元素A ,结果为 枚举 B
        var cc = (b & Emergency.B) != 0;//检查组合状态是否包含枚举B  和b.HasFlag(Emergency.B)应该是等效的啊~~

应用和注意:

  • 一般可用于参数、属性等用来保证强类型
  • 可用于权限叠加、权限判断(一个int就可以表示多个权限)
  • 推荐给枚举提供一个None=0的枚举值
  • 记得是2的指数

转自:http://note.youdao.com/share/?id=fada4ddcb49bdc068c85eb5c3d0bc93a&type=note#/

以上是关于标志枚举的主要内容,如果未能解决你的问题,请参考以下文章

第十五章 枚举类型和位标志

标志枚举

14.VisualVM使用详解15.VisualVM堆查看器使用的内存不足19.class文件--文件结构--魔数20.文件结构--常量池21.文件结构访问标志(2个字节)22.类加载机制概(代码片段

打印标志枚举作为单独的标志

带有红宝石集合/可枚举的酷技巧和富有表现力的片段[关闭]

带有标志属性的 Enum.TryParse