FlagsAttribute是什么?

FlagsAttribute特性的使用还是很常见的,他只能应用于Enum枚举数,下面是官方文档的说明
(官方文档:https://docs.microsoft.com/en-us/dotnet/api/system.flagsattribute?view=netframework-4.7.2)

Indicates that an enumeration can be treated as a bit field; that is, a set of flags.

用于表明一个枚举可以当作位标志来处理.即一组标志。简单说:当我们在使用枚举的值与值之间进行组合的时候(按位OR),Flags属性可以给我们提供更直观的格式化输出(以字符串的形式输出每个枚举值)方便我们调试,即改变了System.Enum的ToString和Format的行为。

枚举Enumerationk中定义的值通常是互斥的,比如方向,颜色,我们在只涉及到一种值的情况下,不需要考虑,但有些需求是会出现值与值之间存在可能的组合关系(combination),而且这种需求会在开发中非常的实用。

比如前面讲过的反射(Reflection),我在通过字符串搜索成员的时候,需要指定BindingFlags(枚举),我可能要同时包含Instance,Public,NoPublic,DeclaredOnly等等多个条件,这时候使用位操作是最简单的方法。而使用FlagsAttribute可以给我们带来更多的便利性(当然实现位操作他不是必要的)

实现元素的组合,要对枚举(Ennumeration)的值有要求,必须是2的N次幂,如1,2,4,8.....
这样定义,每一个值都占有一个独立的位,相当于开关,不会重叠,如下图:

40596e8059b382e6ff79a1b6a55fa33.png

通过位|(OR)操作符,将需要的位打开,如:

public enum Vegetables
    {
        Cabbage = 1<<0,
        Carrot = 1<<1,
        Cuke = 1<<2,
        Potato = 1<<3,
    }

......
Vegetables vegetables = Vegetables.Cabbage | Vegetables.Carrot | Vegetables.Cuke | Vegetables.Potato;
//vegetables里同时包含了4种蔬菜,结果是:15,如图所示:

249cd997ee2862ecd9b7ced04212fc0.png

这时候在控制台输出vegetables的值,打印出来15,因为15这个值在枚举中并没有定义过,但通常这种输出的值并不利于我们调试,我们无法马上知道15或是其它值是由哪些值组合而来的,我们希望能够更直观的看到他们,在这里使用FlagsAttribute可以对位标志的值提供更好的格式化输出,以字符串的形式呈现。

如我们将枚举修改如下:

[Flags]//添加Flags属性
public enum Vegetables
    {
        Cabbage = 1<<0,
        Carrot = 1<<1,
        Cuke = 1<<2,
        Potato = 1<<3,
    }

这时候再输出vetegables的值,控制台会输出如下:

Cabbage, Carrot, Cuke, Potato

这样的结果才方便我们去调试.

在将这些值组合起来之后,我如何验证我是否包含了哪个值?即是否打开了哪个开关?
通过位&(AND)操作符

bool containCarrot = (vegetables&Vegetables.Carrot) == Vegetables.Carrot;

如图:


37574caa2b7bddbe3bcfb65e5fa81c0.png

二进制1111和0010进行位&运算,结果是0010,Carrot位是打开的

如何关闭已经打开的位标志?
实际上就是将该位设置为0.比如我要关闭(删除)Carrot这个值
代码如下:

vegetables &= (~Vegetables.Carrot);

1111&=(~0010)=1111&=1101
结果为:13(Cabbage, Cuke, Potato)
(这里就不再上图了)

位标志的用途非常多,多条件的需求,除了上面说到的反射(多条件查询BindingFlags),比如主角的被动技能,加速,回血,无敌,防御力,xx力提升等等,可以同时作用于角色,通过位标志的组合可以很方便的实现该功能.


到此为止,如果大家发现有什么不对的地方,欢迎指正,共同提高,感谢您的阅读!

编辑于2018.7.12

--闲言碎语


e156177364ebf38d2c4b7c90ef239d6.png

(最近知了猴又出来了,每年都要拿着手电筒去树上找,这是小时候最快乐的趣事儿之一,那时候会抓回来炸着吃,飞来飞去的就用蜘蛛网或塑料袋做成的捕捉工具来抓,然后烤着吃,味道非常香...)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 1.编译程序(1)gcc xx.c,他会默认生成一个a.out的可执行文件,在a.out所在目录,执行./a.o...
    萌面大叔2阅读 5,138评论 0 1
  • 在一个方法内部定义的变量都存储在栈中,当这个函数运行结束后,其对应的栈就会被回收,此时,在其方法体中定义的变量将不...
    Y了个J阅读 9,932评论 1 14
  • .bat脚本基本命令语法 目录 批处理的常见命令(未列举的命令还比较多,请查阅帮助信息) 1、REM 和 :: 2...
    庆庆庆庆庆阅读 12,655评论 1 19
  • 主题模型为非监督模型,且都需要构造一个矩阵,推测的是隐含的主题或者模式(如偏好)。都会变换出对矩阵中纵横两个维度的...
    吹洞箫饮酒杏花下阅读 4,455评论 0 1
  • 趁青春还剩下一点点的余温,温暖着你的眼泪,我不怕寒冷,迎着这岁月的风。 谷雨节气,春天已经走到了最后,夏天就要来了...
    是丁二呀阅读 1,454评论 0 1

友情链接更多精彩内容