C# v4 SDKs now generate a hardened enum shape. Every enum is a sealed record over an open or closed root, so the SDK is explicit about whether a value the API sends but the specification does not list is accepted or rejected.
Details
Enums generated from your schemas are open. An open enum accepts a value the specification does not list, keeps it with the server's own casing and writes it back unchanged, so a new member on the server never breaks an existing client. The server-environment enum is closed and rejects an unknown value on deserialization.
Every enum exposes a get-only Value and converts implicitly to its underlying string or long. TryGetKnownValue resolves a raw value to a declared constant, IsKnownValue tells a declared value from an undeclared one, and Is and == compare against a raw value without constructing an enum. A generated Match takes one arm per declared value plus an otherwise arm for anything undeclared. Integer enums hold long values.
The converters support enums as dictionary keys without reflection, so a map keyed by an enum round-trips through System.Text.Json as the specification describes it.
Usage Example
Set an enum from its constant, and branch on a received value with Match:
var request = new ListOrdersRequest { Status = OrderStatus.Shipped };
var orders = await client.Orders.ListOrders(request);
foreach (var order in orders)
{
var label = order.Status.Match(
onPending: () => "Waiting to ship",
onShipped: () => "On its way",
onDelivered: () => "Delivered",
otherwise: raw => $"Unknown status '{raw}'");
Console.WriteLine($"{order.Id}: {label} ({order.Status.Value})");
}
Use .Value rather than ToString() or string interpolation when the wire value leaves your process.
This feature is available in the C# v4 SDK (beta). Generate it from the APIMatic CLI:
apimatic sdk generate --language=csharp --codegen-version=v4 --stability=beta
For the full set of flags and options, see the APIMatic CLI documentation.