EnumCraft.Core
1.0.1
dotnet add package EnumCraft.Core --version 1.0.1
NuGet\Install-Package EnumCraft.Core -Version 1.0.1
<PackageReference Include="EnumCraft.Core" Version="1.0.1" />
<PackageVersion Include="EnumCraft.Core" Version="1.0.1" />
<PackageReference Include="EnumCraft.Core" />
paket add EnumCraft.Core --version 1.0.1
#r "nuget: EnumCraft.Core, 1.0.1"
#:package EnumCraft.Core@1.0.1
#addin nuget:?package=EnumCraft.Core&version=1.0.1
#tool nuget:?package=EnumCraft.Core&version=1.0.1
EnumCraft.Core
Type-safe enumerations and flags with rich metadata for .NET
What is EnumCraft.Core?
EnumCraft.Core provides type-safe alternatives to standard C# enums with rich metadata and compile-time safety. It replaces raw int, string, and Guid values — and unsafe [Flags] enums — with strongly-typed abstractions that make intent explicit and mistakes compile-time visible.
Features
✅ TypedEnums — Smart enumerations with rich metadata
✅ TypedFlags — Type-safe bitwise flags (like [Flags] but better)
✅ Multiple ID Types — Support for int, long, short, Int128, Guid, string
✅ Extensibility — Easy to extend with custom behavior
✅ Multi-Targeted — Works with .NET Framework 4.7.2+ and .NET 8+
Quick Start
Installation
dotnet add package EnumCraft.Core
TypedEnum Example
using EnumCraft;
public class DocumentType : TypedEnumInt<DocumentType>
{
public static readonly DocumentType Invoice = new(1, "Invoice", nameof(Invoice));
public static readonly DocumentType PurchaseOrder = new(2, "Purchase Order", nameof(PurchaseOrder));
public static readonly DocumentType CreditMemo = new(3, "Credit Memo", nameof(CreditMemo));
private DocumentType(int id, string description, string code)
: base(id, description, code) { }
}
// Rich metadata
DocumentType.PurchaseOrder.ID; // 2
DocumentType.PurchaseOrder.Description; // "Purchase Order"
DocumentType.PurchaseOrder.Code; // "PurchaseOrder"
// Safe lookup
var type = DocumentType.GetByID(1); // Invoice
var all = DocumentType.GetAll(); // ordered list of all values
// Unknown ID throws immediately — no silent failures
var bad = DocumentType.GetByID(999); // ArgumentOutOfRangeException
TypedFlag Example
using EnumCraft;
public class Permissions : TypedFlagInt<Permissions>
{
public static readonly Permissions None = new(0, "None", nameof(None));
public static readonly Permissions Read = new(1, "Read", nameof(Read));
public static readonly Permissions Write = new(2, "Write", nameof(Write));
public static readonly Permissions Execute = new(4, "Execute", nameof(Execute));
public static readonly Permissions All = new(7, "All", nameof(All));
private Permissions(int id, string description, string code)
: base(id, description, code) { }
}
// Combine with standard bitwise operators
var readWrite = Permissions.Read | Permissions.Write;
// Check flags
readWrite.HasFlag(Permissions.Read); // true
readWrite.HasFlag(Permissions.Execute); // false
readWrite.HasAnyFlag(Permissions.Execute, Permissions.Write); // true
readWrite.HasAllFlags(Permissions.Read, Permissions.Write); // true
// Decompose back to individual flags
var flags = readWrite.ToFlags(); // [Permissions.Read, Permissions.Write]
// Logical NOT using All
var withoutRead = Permissions.All & ~Permissions.Read; // Write | Execute
Combined flag instances are cached - (A | B) == (A | B) holds true.
Available Types
TypedEnum Variants
| Type | ID Type | Use Case |
|---|---|---|
TypedEnumShort / TypedEnumInt16 |
short |
Compact storage |
TypedEnumInt / TypedEnumInt32 |
int |
Default choice — most common |
TypedEnumLong / TypedEnumInt64 |
long |
Large ID ranges |
TypedEnumInt128 |
Int128 |
Very large ID ranges (.NET 7+) |
TypedEnumGuid |
Guid |
Globally unique, stable across environments |
TypedEnumString |
string |
Human-readable IDs |
TypedFlag Variants
| Type | ID Type | Max Flags |
|---|---|---|
TypedFlagShort / TypedFlagInt16 |
short |
15 distinct flags |
TypedFlagInt / TypedFlagInt32 |
int |
31 distinct flags |
TypedFlagLong / TypedFlagInt64 |
long |
63 distinct flags |
TypedFlagInt128 |
Int128 |
127 distinct flags (.NET 7+) |
Why EnumCraft?
vs. Standard Enums
Standard Enum:
public enum DocumentType
{
Invoice = 1,
PurchaseOrder = 2
}
// Problems:
var type = (DocumentType)999; // Compiles — runtime chaos
string desc = type.ToString(); // Just "999" — not helpful
TypedEnum:
var type = DocumentType.GetByID(999); // Throws ArgumentOutOfRangeException immediately
string desc = type.Description; // "Invoice" — rich metadata
vs. String Constants
String Constants:
public static class DocType
{
public const string Invoice = "invoice";
public const string PurchaseOrder = "purchase_order";
}
// Problems - enforcement breaks at the call site:
public void ProcessDocument(string documentType) { ... }
ProcessDocument("invoce"); // Typo - compiles, fails silently at runtime
ProcessDocument("INVOICE"); // Wrong casing - compiles, fails silently at runtime
ProcessDocument("anything here"); // Completely invalid - compiles, fails silently at runtime
TypedEnum:
public void ProcessDocument(DocumentType documentType) { ... }
ProcessDocument(DocumentType.Invoce); // CS0117 - compile error
ProcessDocument("invoice"); // CS1503 - compile error
ProcessDocument(DocumentType.Invoice); // ✅ only valid usage compiles
Advanced Features
ToString Format Specifiers
var type = DocumentType.PurchaseOrder;
type.ToString("D"); // "Purchase Order" - Description (default)
type.ToString("C"); // "PurchaseOrder" - Code
type.ToString("I"); // "2" - ID as string
type.ToString("F"); // "ID: 2, Description: Purchase Order, Code: PurchaseOrder"
type.ToString("G"); // "ID: 2, Code: PurchaseOrder"
type.ToString("f"); // "PurchaseOrder (2): Purchase Order"
type.ToString("g"); // "PurchaseOrder (2)"
// Works in string interpolation too
Console.WriteLine($"{type:C}"); // "PurchaseOrder"
Inactive Entries
Mark deprecated entries with [Obsolete] to prevent new usage while keeping them retrievable for historical data:
public class DocumentType : TypedEnumInt<DocumentType>
{
public static readonly DocumentType Invoice = new(1, "Invoice", nameof(Invoice));
[Obsolete("DO NOT USE: Replaced by Invoice", true)]
public static readonly DocumentType LegacyInvoice = new(2, "Legacy Invoice", nameof(LegacyInvoice), active: false);
private DocumentType(int id, string description, string code, bool active = true)
: base(id, description, code) { ... }
}
// New code referencing LegacyInvoice causes a build error GetByID(2) still works — for archived data retrieval only
var archived = DocumentType.GetByID(2);
TypedFlag Decomposition
var combined = Permissions.Read | Permissions.Write | Permissions.Execute;
foreach(var flag in combined.ToFlags())
{
Console.WriteLine(flag.Code);
}
// Output: Read, Write, Execute
combined.IsSingleFlag(); // false
Permissions.Read.IsSingleFlag(); // true
JSON Serialization
JSON serialization for TypedEnum and TypedFlag is available via the separate EnumCraft.Json package:
dotnet add package EnumCraft.Json
using EnumCraft.Json;
DocumentType.Invoice.AsJsonString();
// {"id":1,"description":"Invoice","code":"Invoice"}
Framework Support
| Framework | Supported |
|---|---|
| .NET Framework 4.7.2+ | ✅ |
| .NET Standard 2.0+ | ✅ |
| .NET 8+ | ✅ (enhanced generics via IBitwiseOperators) |
Related Packages
- EnumCraft.Json — JSON serialization extensions for TypedEnum and TypedFlag
- EnumCraft.FeatureFlags — Provider-based feature flags built on TypedEnumGuid
- EnumCraft.FeatureFlags.Json — JSON file provider for feature flags
License
MIT — see LICENSE for details.
Author
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
-
net8.0
- No dependencies.
NuGet packages (2)
Showing the top 2 NuGet packages that depend on EnumCraft.Core:
| Package | Downloads |
|---|---|
|
EnumCraft.FeatureFlags
Feature Flags engine built on EnumCraft.Core. |
|
|
EnumCraft.Json
JSON serialization extensions for EnumCraft.Core TypedEnum and TypedFlag instances with structured output and decomposed flags support |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.1 | 262 | 4/26/2026 |
| 1.0.0 | 238 | 4/26/2026 |
| 0.3.1-preview | 232 | 4/22/2026 |
| 0.3.0-preview | 239 | 4/20/2026 |
| 0.2.2-preview | 246 | 4/6/2026 |
| 0.2.1-preview | 254 | 3/2/2026 |
| 0.2.0-preview | 244 | 2/24/2026 |
| 0.1.4-preview | 194 | 2/22/2026 |
| 0.1.3-preview | 203 | 2/19/2026 |
| 0.1.2-preview | 200 | 2/17/2026 |
| 0.1.1-preview | 161 | 2/16/2026 |
| 0.1.0-preview | 167 | 2/16/2026 |