mirror of
https://github.com/microsoft/BCQuality.git
synced 2026-10-05 22:56:55 +01:00
74 lines
2.1 KiB
Markdown
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.
|