Repository navigation
A closed-set member's external name, apart from its identifier (spike first) #185
Description
Problem
A closed-set member is its C# field's name everywhere: parsing, JSON, the EF Core column, the OpenAPI enum and the fault identifiers. So renaming a field changes stored data and the wire contract, and a closed set can't be stored or sent as a number or a fixed key. Ardalis.SmartEnum, Intellenum, Thinktecture.Runtime.Extensions and EricksonLopez.DomainPrimitives all allow a value apart from the identifier (docs/comparison.md, "Choose something else when"). The roadmap lists this under "2.x, with a spike first" (proposed in the review of 2026-10-13).
Change
A spike first, under spikes/, with a README giving the question, the answer and the evidence. It decides:
- How a member declares its external name. It must be declared, not inferred, and must survive Native AOT. Options are a constructor argument, an attribute on the field, or a key type on the set's interface.
- Whether a number is in scope, or only a string apart from the identifier.
- What follows the name at once:
Parse/TryParse(andignoreCase), JSON, the EF Core column and its translation, the OpenAPI enum, and fault identifiers. A partial rollout would make the name different in different places. - The refusals. Two members with one external name, or with names that differ only in case under
ignoreCase, need a generator error like CMTK1021. An Error is allowed in a minor because only the new API can write that form (decision 118). - What existing sets do. A set that declares no external name keeps today's behaviour byte for byte.
Then either the feature lands in 2.4.0 under a decision record, or the spike's answer moves it back to the roadmap with the reason.
Done when
- The spike's README answers the questions above, and a decision record states the choice.
- If it lands:
- Parsing, JSON, EF Core, OpenAPI and faults all use the external name, each with a test.
- The refusals are tested.
- The closed-set docs, the Generators README, the comparison's closed-set table and the changelog say so.
- Claims in
test/oracles/claims.jsonhold it.
Activity