diff --git a/graph/patterns/enums.md b/graph/patterns/enums.md index 080435af..47538134 100644 --- a/graph/patterns/enums.md +++ b/graph/patterns/enums.md @@ -102,6 +102,72 @@ Additionally speaking, depending on the situation, a nullable enum can very like If used, `EnumType` names should be singular if the are non-flags enums, and the names should be plural if they are flags enums. + +#### Nullable enums + +Enum properties can be marked `Nullable="true"`, which means the property can hold `null` in addition to any defined member. +Before making an enum property nullable, consider whether a sentinel member like `none` better communicates the intent. + +##### `null` vs `none` + +| Value | Meaning | Use when | +|---|---|---| +| `null` | The property has no value — it was never set or is not applicable | The absence of a value is semantically different from every defined member | +| `none` | An explicit "nothing selected" choice within the enum's domain | "No selection" is a valid, intentional state the caller can set | + +> **Note:** The `unknownFutureValue` sentinel is always required as the last known member of every enum (see [evolvable enums](./evolvable-enums.md)). +> It is unrelated to nullability and must be present regardless of whether the property is nullable or uses a `none` member. + +##### Prefer a `none` member over nullable + +In most cases, add a `none` member (value `0`) instead of making the property nullable. +This keeps the property non-nullable, which is simpler for SDK consumers and avoids the three-way ambiguity of "is it null, is it none, or is it a real value?" + +```xml + + + + + + + + + + +``` + +##### When nullable is appropriate + +Use `Nullable="true"` on an enum property only when **all** of the following apply: + +1. **Absence is meaningful** — `null` represents "not set" or "not applicable," which is semantically distinct from every enum member including a hypothetical `none`. +2. **A sentinel member would be misleading** — adding `none` would imply the caller actively chose "nothing," but the actual semantics are that the property doesn't apply to this instance. +3. **The property is optional on creation** — the service does not assign a default value; `null` is the expected state until the caller explicitly sets one. + +```xml + + +``` + +##### Anti-pattern: nullable + `none` + +Do **not** combine a nullable enum with a `none` member. +This creates two ways to express "no value" and forces callers to handle both `null` and `none`, leading to inconsistency and bugs. + +```xml + + + + + + + + + +``` + +Pick one: either `none` with `Nullable="false"`, or no `none` member with `Nullable="true"`. + #### Flag Enums or Collection of Enums In case an enum can have multiple values at the same time the tentation is to model the property as a collection of Enums: