C# Smart Enums: 고급
Source: Dev.to

The Problem: The Copy-Paste Trap
Part 2에서는 고성능 O(1) 사전 조회를 구현했습니다. 하지만 애플리케이션에 수십 개의 상태 유형(주문, 결제, 사용자 등)이 있다면, 같은 사전과 조회 로직을 반복해서 복사‑붙여넣기하게 될 수도 있습니다.
A Suggestion: An Advanced Generic Base Class
To keep your code DRY (Don’t Repeat Yourself), we can move the “heavy lifting” into a single abstract base class. This allows your specific status classes to focus purely on defining their values while inheriting all the optimized lookup logic for free.
The implementation uses the Curiously Recurring Template Pattern (CRTP). It ensures that each specific Smart Enum (like ProductStatus) maintains its own private dictionary in memory, preventing data collisions between different types.
구현
우리는 모든 값에 Id가 존재하도록 보장하는 간단한 interface를 정의하고, 데이터를 안전하게 접근할 수 있는 여러 방법을 제공하는 기본 class를 구현합니다.
사용 예시
초기화가 완료되면, Smart Enum을 사용하는 방법에 대해 완전한 유연성을 가집니다.
// Initialize once at startup (e.g., Program.cs)
ProductStatus.Initialize();
// Example 1: Strict access (expects ID to exist)
var status = ProductStatus.Get(1);
Console.WriteLine(status.Description);
// Example 2: Safe access with null check
var maybeStatus = ProductStatus.GetOrDefault(99);
if (maybeStatus != null) { /* Do something */ }
// Example 3: Pattern matching for clean branching
if (ProductStatus.TryGet(2, out var foundStatus))
{
Console.WriteLine($"Found: {foundStatus?.Description}");
}
왜 이것이 견고한 아키텍처 선택인지
- 유연한 사용 – 비즈니스 흐름에 따라 예외, null, 또는 불리언 중 선택할 수 있습니다.
- 엄격한 타입 안전성 –
TSelf제약 조건은ProductStatus.Get()이 직접ProductStatusValue를 반환하도록 보장하며, 형변환이 필요 없습니다. - 리플렉션 없음 –
Initialize()를 사용함으로써 어셈블리 스캔의 성능 오버헤드를 피합니다. - 보일러플레이트 제로 – 특정 열거형 클래스는 데이터에만 집중하고, 엔진은 기본 클래스에 캡슐화됩니다.
직접 해보세요
버전 노트
이 고급 구현은 .NET 6 이상이 필요합니다. CRTP와 최신 제네릭 제약 조건을 사용하면 현대 C# 환경에서 타입 안전성과 성능을 보장합니다.
추가 읽을거리 및 리소스
- Microsoft Docs: Generic Constraints
- Ardalis.SmartEnum: GitHub Repository – 프로덕션 등급 스마트 열거형을 위한 업계 표준.