SafeMapX — C#에서 널 체크, 삼항 연산자 및 String Plumbing을 없애는 새로운 범용 패턴
Source: Dev.to
SafeMapX — C#에서 널 체크, 삼항 연산자 및 문자열 처리 코드를 없애는 새로운 범용 패턴
대규모 C# 시스템에서 작업해 본 모든 엔지니어가 겪는 고통:
- 끝없이 이어지는
if (x != null)계단식 구조 - 중첩된 프로퍼티 체인
- 삼항 연산자 안에 또 다른 삼항 연산자
string.IsNullOrWhiteSpace()로 인한 잡음- 한 객체 그래프에서 다른 객체 그래프로의 취약한 매핑
- 방어 로직 안에 파묻힌 Repository 호출
이 모든 것이 동작은 하지만, 코드가 복잡하고 표현력이 약하며 팀마다 일관성이 떨어집니다.
SafeMapX 소개: C#용 통합 방어 로직 패턴
SafeMapX는 다음과 같은 코드를:
if (customer != null &&
customer.Profile != null &&
customer.Profile.Address != null &&
customer.Profile.Address.City != null)
{
return customer.Profile.Address.City.Name;
}
return "Unknown";
다음과 같이 바꿔줍니다:
var city = Safe.Guard(customer)
.Map(c => c.Profile)
.Map(p => p.Address)
.Map(a => a.City)
.Map(c => c.Name)
.Default("Unknown")
.Value();
읽기 쉽고, 유창하며, 예측 가능하고, 분기가 없으며, 잡음도 없습니다.
SafeMapX가 작동하는 이유
- Guard는 객체를 안전한 컨텍스트로 감싸줍니다.
- Map은 그래프를 한 단계씩 이동합니다.
- 단락(short‑circuit) 평가가 자동으로
null에서 멈춥니다. - Default는 최종 폴백 값을 제공합니다.
- **Value()**는 결과를 깔끔하게 추출합니다.
이 패턴은 예외도, 널 레퍼런스도, 난잡한 코드도 없는 보편적인 방어 로직이 됩니다.
DeepPath — 모든 것을 한 줄로 탐색
var city = Safe.Path(customer, x => x.Profile.Address.City.Name)
.Default("Unknown")
.Value();
다중 단계 매핑이 필요 없습니다. 한 줄의 깔끔한 의미 표현입니다.
비동기 Repository 체인 (일반적인 엔터프라이즈 사용 사례)
var result = await Safe.Guard(await repo.GetCustomer(id))
.MapAsync(c => repo.GetProfile(c.ProfileId))
.MapAsync(p => repo.GetAddress(p.AddressId))
.Map(a => a.City?.Name)
.Default("Unknown")
.ValueAsync();
실제 비즈니스 로직을 크게 변형시킵니다.
SafeString — IsNullOrWhiteSpace 를 영원히 없애다
var result = Safe.String(input)
.Trimmed()
.WhenEmpty("N/A")
.Value();
목표
SafeMapX는 단순한 헬퍼 라이브러리가 아니라 전사적으로 채택돼야 할 새로운 패턴입니다:
- 더 읽기 쉬운 코드
- 방어적 잡음 감소
- 의도 명확화
- 레이어 간 안전한 매핑
- 테스트 가능한 파이프라인
- 인라인 함수형 변환
GitHub Repository
https://github.com/sandeepbassioec/safemap/
결론
SafeMapX는 또 다른 유틸리티 라이브러리가 아니라 C#에서 방어 로직을 표현하는 새로운 방법입니다.
기업 코드에 ??, ?., if (x != null) 가 난무한다면, 오늘 바로 SafeMapX를 시도해 보세요.