NULL 안전 시스템과 핵심 연산자
C# 언어의 NullReferenceException 예외를 처리하는 현대적 연산자들은 다음과 같다.
| 연산자 | 명칭 | 분석 |
|---|---|---|
| ?. | 널 조건부 연산자 | 참조가 null이면 멤버 접근을 하지 않고 즉시 null을 반환한다. 단일 연결뿐 아니라 a?.b?.c?.d 처럼 체이닝 시 가독성이 극대화된다. |
| ?? | 널 병합 연산자 | 왼쪽 값이 null일 때만 오른쪽의 기본값을 반환한다. DB 조회나 설정값 로드 시 유용하다. |
| ?? = | 널 병합 할당 | 변수가 null일 때만 우측 값을 할당한다. 지연 초기화(Lazy Initialization) 패턴을 한 줄로 구현할 수 있다. |
| ! | 널 용서 연산자 | 컴파일러의 경고를 강제로 끈다. 로직 상 절대 null이 아님을 확신할 때 사용한다. |
패턴 매칭의 정수
패턴 매칭(Pattern Matching)은 데이터의 타입을 확인하고 값을 추출하며, 조건을 검사하는 과정을 하나로 합친 기술이다.
- 타입 패턴과 선언 패턴: 확인과 동시에 변수 선언이 가능한 방법이다.
if (item is Tool { IsPowerTool: true } powerTool)
{
// item이 Tool 타입이고, IsPowerTool 속성이 true일 때만 진입
// 변수 powerTool을 블록 내부에서 즉시 사용 가능
}
-
관계 패턴 및 논리 패턴: C# 9.0 이후 숫자의 범위를 검사할 때 더 이상 &&, 연산자 사용하지 않고 가독성을 높이는 방법이다.
bool isCritical = temperature is < 0 or > 100; // 직관적인 논리 전개
bool isWarm = temperature is >= 18 and <= 26;
switch 식
C# 8.0 이후 switch 식은 명령을 내리는 문장(Statement)에서 결과를 반환하는 식(Expression)으로 변경됬다.
| 특징 | 기존 switch 문 | 현대 switch 식 |
|---|---|---|
| 문법 | case, break, default 필수 | =>(Lambda)와 _(Discard)사용 |
| 반환값 | 직접 변수에 할당 필요 | 식 자체가 값을 반환 |
| 가독성 | 중복 코드 존재 | 표 형식으로 간결 |
예제 코드는 다음과 같다.
var stateDescription = deviceState switch
{
State.Active => "정상 동작 중",
State.Idle => "대기 모드",
State.Error => "오류 발생!",
_ => "알 수 없는 상태" // default 케이스
};
비트 연산과 [Flags] 시스템
성능과 메모리가 중요한 환경에서는 여러 상태를 하나의 정수형 변수에 담는 비트 플래그를 사용한다.
-
[Flags]속성: 이 속성을 Enum 위에 선언하면 비트 연산(&,)시 디버깅 창에서 State.A State.B와 같이 이름을 보여준다. -
비트 연산: 추가는 state = State.Running; 제거는 state &= ~State.Running; 확인은 state.HasFlag(State.Running); 다음과 같이 내부적으로 비트 연산을 수행한다.