按位枚举转换值不是预期的

时间:2009-10-20 19:14:53

标签: c# enums bit-manipulation

我有以下枚举:

[Flags]
    public enum PermissionLevel {
        User = 1,
        Administrator = 2,
        ITStaff = 3,
        Manager = 4,
        SuperAdministrator = 6,
    }

当我这样做时:

PermissionLevel permission = (PermissionLevel) dr.GetInt32(i);

我获得了分配给权限对象的随机权限值。例如,如果 i 为6,我的权限对象将返回“Administrator | Manager”,我应该得到“SuperAdministrator”。当我将实例强制转换为整数时,它返回6。

我错过了什么吗?

3 个答案:

答案 0 :(得分:11)

您需要确保每个值组合都是唯一的:

[Flags]
public enum PermissionLevel {
    User = 1,
    Administrator = 2,
    ITStaff = 4,
    Manager = 8,
    SuperAdministrator = 16
}

正如您的枚举目前所见,6可以表示SuperAdministratorAdministrator | Manager。 4可以是ManagerUser | ITStaff,依此类推。

答案 1 :(得分:4)

关于它没有任何随意性。如果权限为6,则二进制值为110。有两个活动标志(值为1的位),值为4(位)的位和2(管理员)。您设置的SuperAdministrator值6实际上是ManagerAdministrator的组合。

有时这是你想要的行为,但似乎不是你的情况。然后,您应该更改枚举,以便每个值代表一个唯一的位,正如其他答案所示。

答案 2 :(得分:3)

当用Flags属性修饰时,你可以做你正在做的事情,它完全没问题.CLR告诉你,分配给枚举实例的值是和管理员或管理器......那是什么垂直管道是,按位Or运算符。
从msdn页面msdn Flags Attribute

  

“考虑创建枚举   常用标志的常量   组合。例如,如果你有   用于文件I / O的枚举   包含的操作   枚举常量Read = 1和   写= 2,考虑创建   枚举常量ReadWrite = Read   或写,结合了Read和   写标志。另外,按位   OR操作用于组合标志   可能被认为是先进的   在某些情况下的概念   不应该要求简单   任务“。

您可以轻松地声明枚举如下:

   [Flags]public enum PermissionLevel 
    {        
       User = 1,        
       Administrator = 2,        
       ITStaff = User | Administrator,        
       Manager = 4,        
       SuperAdministrator = Administrator | Manager ,    
    }

哦,顺便说一下,总是包含一个无值的...

是一种很好的做法
    [Flags]public enum PermissionLevel 
    { 
       None = 0,       
       User = 1,        
       Administrator = 2,        
       ITStaff = User | Administrator,        
       Manager = 4,        
       SuperAdministrator = Administrator | Manager ,    
    }

这种技术非常有用,因为它允许客户端代码使用简明扼要地表达实际业务意图的语法来针对各个值的子集测试候选值...假设candValue是核心个体值之一... < / p>

 if ((candValue & PermissionLevel.SuperAdministrator) == candVal) 
     // tests to see if candValue is Administrator Or Manager 

如果您无法访问代表SuperAdministrator位掩码的枚举值= 00000110

,则需要进行2次比较