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

74 lines
2.1 KiB
Markdown

---
bc-version: [all]
domain: style
keywords: [enum, option, integer, magic-number, variable-typing, field-typing]
technologies: [al]
countries: [w1]
application-area: [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
```al
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
```al
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.