(转载)C# 枚举 FlagsAttribute用法

 这是读过几篇文章后发现整理的最完整的一篇文章

  转载地址:枚举特性FlagsAttribute的用法

先看官方的解释:指示可以将枚举作为位域(即一组标志)处理。

看起来并不好理解,到底什么是作为位域处理?

其实说的通俗点就是用二进制的表示方式来处理数学集合概念中关于集合的或与非等运算方法。

有什么用

所有可以抽象成数学集合模型的业务逻辑都可以使用该方法来处理。

举个栗子:

在设计IO系统时,我们需要使用一个数据结构来表示IO系统的操作权限。

分别为读取权限写入权限修改权限执行权限

在为用户添加权限时需要为用户分配一个权限值,而在使用IO功能时则需要判断该用户的权限值是否包含某个功能的权限。

 

这个业务场景就非常适合用数据的集合模型来处理。

每一种权限用一个集合来表示。

为用户分配的权限就用一个所有允许权限的总集合来表示。

在使用功能的时候,用户分配权限的集合是否包含该功能权限的集合的算法来处理。

用二进制的表示方式

还是上面的例子,分别是读取权限,写入权限,修改权限,执行权限四个权限。

我们用4位长度的二进制数字来表示:

 

第0位表示读取;

第1位表示写入;

第2位表示修改;

第3位表示执行;

而每一个位置上的数字0表示不包含,1表示包含,即0表示没有该权限,1表示有该权限。

 

因此每种权限分别对应的二进制数字分别是:

读取:0001;

写入:0010;

修改:0100;

执行:1000;

 

当为一个用户分配权限的时候,比如需要分配的权限为读取,写入,修改3个权限。

我们可以用二进制的或运算来表示集合的求并集。

0001 | 0010 | 0100 = 0111;

该用户的权限可以用二进制的0111来表示。

在使用的功能的时候,比如我要读取某文件,需要判断是否包含读取功能。

我们可以用二进制的与运算来求用户权限与读取权限的交集是否与读取权限相等的方式,来表示集合的求是否包含。

0111 & 0001 = 0001;

结果0001与读取权限0001相等,因此用户可以使用读取功能。

用C#代码如何实现

权限定义:

1
2
3
4
5
6
7
8
[Flags]
public enum IoPermission
{
    Read = 1,   //读取权限:0001的十进制值为1
    Write = 2,  //写入权限:0010的十进制值为2
    Edit = 4,   //修改权限:0100的十进制值为4
    Run = 8,    //执行权限:1000的十进制值为8
}

为用户设置权限:

1
var userPermission = IoPermission.Read | IoPermission.Write | IoPermission.Edit;

判断功能是否可用:

1
var readEnabled = (userPermission & IoPermission.Read) == IoPermission.Read;

另外,权限的定义还可以用位移元算来表示:

1
2
3
4
5
6
7
8
[Flags]
public enum IoPermission
{
    Read = 1 << 0,   //读取权限:1按照二进制的表示向左位移0位,即0001
    Write = 1 << 1,  //写入权限:1按照二进制的表示向左位移1位,即0010
    Edit = 1 << 2,   //修改权限:1按照二进制的表示向左位移2位,即0100
    Run = 1 << 3,    //执行权限:1按照二进制的表示向左位移3位,即1000
}

 

更多的计算方法,和更多的应用场景,读者可以自行研究。

posted @ 2018-12-11 16:41  静思长远  阅读(390)  评论(0编辑  收藏  举报