bcquality/custom/knowledge/style/fixed-choice-set-must-use-enum-not-integer.md
2026-08-12 22:30:48 +02:00

2.1 KiB

bc-version domain keywords technologies countries application-area
all
style
enum
option
integer
magic-number
variable-typing
field-typing
al
w1
all

A fixed set of named choices must use Enum, not a raw Integer

Description

When a variable or field can only take on a fixed set of more than two named, mutually exclusive states — a difficulty level, a document type, a processing status — it must be typed as Enum (or Option when extending an object that still uses the legacy type). Representing that same state as a plain Integer and tracking the meaning of each value in a comment or in the developer's head (1 = Beginner, 2 = Intermediate, 3 = Advanced) is a magic-number anti-pattern: the compiler cannot catch an out-of-range value, CASE/IF branches read as opaque numbers instead of names, and every call site must either duplicate the numbering or trust a comment that can go stale.

This is distinct from a true two-state choice — see binary-choice-must-be-boolean — which should be Boolean, not an Enum/Option with two members. The line is the state count: more than two named states is an enumeration question, not a Boolean one.

Best Practice

enum 50100 "Course Difficulty"
{
    Extensible = true;
    value(0; Beginner) { }
    value(1; Intermediate) { }
    value(2; Advanced) { }
}

field(50; Difficulty; Enum "Course Difficulty")
{
}
...
case Difficulty of
    "Course Difficulty"::Beginner:
        Level := 'Beginner';
    "Course Difficulty"::Intermediate:
        Level := 'Intermediate';
    "Course Difficulty"::Advanced:
        Level := 'Advanced';
end;

Anti Pattern

field(50; Difficulty; Integer)
{
}
...
// 1 = Beginner, 2..5 = Intermediate boundary is fuzzy, 6+ = Advanced?
case Difficulty of
    1:
        Level := 'Beginner';
    2, 3:
        Level := 'Intermediate';
end;

A raw Integer standing in for a named set of states pushes the documentation of what each value means into a comment, a wiki page, or a developer's memory — none of which the compiler or a future maintainer can rely on.