是使用> =和< =来指定枚举值好的代码练习吗?

时间:2017-02-23 17:41:15

标签: enums language-agnostic enumeration

我正在和另外8个人一起开展一个项目,并且想知道这里最好的代码实践,因为其他人将在未来几年内使用这个代码。

假设我有一个包含10个值的枚举:

typedef enum {
    Tag1 = 1,
    Tag2,
    Tag3,
    Tag4,
    Tag5,
    Tag6,
    Tag7,
    Tag8,
    Tag9,
    Tag10
} Tag;

如果我想检查标签是否等于Tag6,Tag7,Tag8,Tag9或Tag10,最好使用比较,如:

if(myTag >= Tag6 && myTag <= Tag10) {
    //Do something
}

或者最好使用OR并检查每个标签吗?

使用&gt; =和&lt; =看起来更好并且不那么笨重,但是如果在线上,有人要在Tag7和Tag8之间插入一个新标签,那么它会搞乱所有逻辑。

我可以期望有人不会在其他标签之间添加新标签吗?

2 个答案:

答案 0 :(得分:4)

是,但表示比例值的枚举,例如:

enum Priority {
    None = 0,
    Low,
    Medium,
    High,
    Critical
}

然后这段代码有意义且可读:

if(message.Priority >= Priority.Medium) {
     // Notify user
}

如果枚举没有表达这样的比例,那么请避免使用<>,因为它们可能相当混乱。改为使用位标志。

标志枚举使用二进制值,以便可以组合值:

enum UserAudiences {
    // Basic values:  dec // binary
    None            = 0,  // 0000
    Client          = 1,  // 0001
    Employee        = 2,  // 0010
    Contractor      = 4,  // 0100
    Key             = 8,  // 1000

    // Combined:      dec // binary
    KeyClient       = 9,  // 1001 : Key + Client          
    BoardMember     = 10, // 1010 : Key + Employee        
    CounterParty    = 5,  // 0101 : Client + Contractor
    BusinessPartner = 13  // 1101 : Key + Client + Contractor
}

然后,在检查组合枚举值时,我们查看二进制数以及是否设置了相应的位。例如,如果我们要检查UserAudiences.Employee,我们可以只查找代表2的位,如果已设置,那么我们有一个包含它的枚举值:

if((message.Audience & UserAudiences.Employee) != 0) {
    // Post on intranet
} else {
    // Send externally
}

无法通过KeyClientContractor枚举的任意组合设置该位,只有在Employee为1时才能设置该位的来源&#39;枚举。

大多数语言都有帮助(或者你可以自己编写):

if(message.Audience.HasFlag(UserAudiences.Employee)) { ...

数学可以在任何基础上运行 - 你可以使用十进制的1,10,100等。但是,你需要更快的数字。

最后,常规枚举使用单数名称,标记枚举使用多个名称,向程序员暗示是使用相等还是按位检查。

答案 1 :(得分:2)

  

我可以期望有人不会在其他标签之间添加新标签吗?

我不会赌它。除非enum的序数/基础值具有一些固有的含义或顺序,否则我会避免使用它们。

我只会使用范围检查,如果我实际上希望某人能够在不调整所有检查的情况下插入其他枚举。这可能是一个相当罕见的情况。 Keith给出了优先级枚举的一个很好的例子,我能想到的另一个例子是日志级别。

确切的语法当然取决于语言,但我通常认为这样的东西最具可读性:

if(myTag in [Tag6, Tag7, Tag8]) {
    // ... 
} 

或者甚至更好地使用一些描述变量名称,这使得其他标签显而易见:

topTags = [Tag6, Tag7, Tag8]

if(myTag in topTags) {
    // ... 
}