Summary#
An enum is a fixed set of named values — enum Status { Draft, Placed, Cancelled } — used as the type of a
member. It gives you a closed vocabulary the compiler checks: a value outside the set is a compile error, not a bad
row. Two small decisions round it out: how it is stored (a number, or its name) and what a human sees (its
label).
Description#
Declaring one#
An enum lists its members; any member or property can then take the enum as its type (an
entity Order { Status Status; }, a function local, a component prop). The compiler enforces the set everywhere the
enum is used, so a typo or a stale value is caught at compile time:
enum Status { Draft, Placed, Cancelled }[Test]
void Status_is_a_fixed_set() {
var s = Status.Placed;
Assert.NotEqual(Status.Draft, s);
}Stored as a number, or as its name#
By default an enum member is stored as a number — compact, and fine when only your own code reads it. When a
human or another system will read the column, store it as the member's own name with [Type(string)], so the
value in the database is "Placed" rather than 1. That is the setting to reach for on anything exported, reported
on, or read by an integration. See enum.
The label a human reads#
A member's stored value is compact; the label on screen doesn't have to be. [Label], [Icon], [Tone] — what a human reads — [Label("…")] — gives
a member a human-readable label (the member's own name is the default), and a doc comment gives it a longer
description. So InProgress can show as "In progress" without changing what is stored.
Its name as text, in memory and in a query#
level.ToString() is the member's name, as in C# — "High", never the stored number. Inside a query over stored rows
it becomes SQL too, so a filter or a projection over it runs in the database:
enum Grade { Low, Mid, High }
entity Route {
[Required, MaxLength(40)] string Name;
Grade Level;
security { allow read when IsAuthenticated; }
}
int HardOnes() => Route.Where(r => r.Level.ToString() == "High").Count();
List<string> Levels() => Route.OrderBy(r => r.Name).Select(r => r.Level.ToString()).ToList();A member is always written qualified (Grade.High), so an app's own const may share a member's name — const string Back = "back"; beside the platform's CameraFacing.Back — and the bare name is the const.
See also#
- enum — declaring the set, and
[Type(string)]for name storage - [Label], [Icon], [Tone] — what a human reads —
[Label]and the human-facing label - Types — the rest of the type system