代码之家  ›  专栏  ›  技术社区  ›  Raúl Roa

不需要按位枚举强制转换返回值

  •  1
  • Raúl Roa  · 技术社区  · 16 年前

    我有以下枚举:

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

    当我这样做时:

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

    我错过什么了吗?

    3 回复  |  直到 16 年前
        1
  •  11
  •   Fredrik Mörk    16 年前

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

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

    正如您的枚举当前所示,6可以表示 SuperAdministrator Administrator | Manager . 4可以是 Manager User | ITStaff 等等

        2
  •  4
  •   Meta-Knight    16 年前

    这不是随机的。如果允许 6 ,二进制值为 110 . 有两个活动标志(值为1的位)、值为4的位(管理器)和2(管理员)。这个 SuperAdministrator 您设置的值6实际上是 Manager Administrator

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

        3
  •  3
  •   Charles Bretana    16 年前

    当使用Flags属性进行装饰时,您可以做您正在做的事情,这非常好。。CLR告诉您分配给枚举实例的值为,并且管理员或管理员。。。这就是垂直管道,一个按位Or运算符。
    msdn Flags Attribute

    “考虑创建枚举 组合。例如,如果你有 用于文件I/O的枚举 枚举常数Read=1和 写= 2,考虑创建 或者写,它结合了读和写 写入标志。此外,按位 或用于组合标志的操作 可能被认为是先进的 在某些情况下 任务。”

    您可以很容易地声明枚举,如下所示:

       [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 ,    
        }
    

    这种技术非常有用,因为它允许客户端代码使用简洁地表达实际业务意图的语法,根据单个值的子集测试候选值。。。假设价值观是核心个人价值观之一。。。

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

    如果无法访问表示SuperAdministrator bitmask=00000110的枚举值,则需要进行2次比较