C#은 null 값을 안전하고 간결하게 처리할 수 있도록 세 가지 전용 연산자를 제공합니다. 이 연산자들을 활용하면 복잡한 조건문 없이도 NullReferenceException을 예방하고 코드의 가독성을 크게 높일 수 있습니다.
1. null 병합 연산자 (??)
null 병합 연산자(??)는 변수의 값이 null이 아닐 경우 해당 값을 그대로 반환하고, null일 경우에만 지정한 기본값을 대신 사용할 수 있게 해주는 연산자입니다.
이 연산자는 기존의 삼항 조건식을 다음과 같이 대체합니다.
string resultOne = value != null ? value : "default_value";
위 코드를 null 병합 연산자를 사용하면 훨씬 간결하게 표현할 수 있습니다.
string resultTwo = value ?? "default_value";
사용 예제
using System;
class Program{
static void Main(){
string input = null;
string choice = input ?? "default_choice";
Console.WriteLine(choice); // default_choice 출력
string finalChoice = choice ?? "not_chosen";
Console.WriteLine(finalChoice); // default_choice 출력
}
}위 예제에서 input이 null이므로 choice에는 기본값인 "default_choice"가 할당됩니다. 반면 choice는 이미 값이 있으므로 finalChoice 역시 "default_choice"를 유지합니다.
2. null 병합 할당 연산자 (??=)
null 병합 할당 연산자(??=)는 왼쪽 피연산자가 null이 아닐 경우 그 값을 그대로 유지하고, null일 경우에만 오른쪽 값을 할당합니다. 즉, 현재 값이 null인 변수에 기본값을 초기화하는 용도로 사용됩니다.
기존에는 다음과 같이 작성해야 했습니다.
if (result == null)
result = "default_value";이 코드를 한 줄로 줄일 수 있습니다.
result ??= "default_value";
이 연산자는 특히 지연 계산(lazy evaluation) 방식의 프로퍼티에서 유용하게 활용됩니다.
사용 예제
class Tax{
private Report _lengthyReport;
public Report LengthyReport => _lengthyReport ??= CalculateLengthyReport();
private Report CalculateLengthyReport(){
return new Report();
}
}위 예제에서는 _lengthyReport가 null일 때만 비용이 큰 보고서를 계산하므로, 불필요한 중복 연산을 방지할 수 있습니다.
3. null 조건부 연산자 (?.)
null 조건부 연산자(?.)는 인스턴스의 메서드나 멤버를 안전하게 호출할 수 있도록 도와줍니다. 인스턴스가 null이면 NullReferenceException을 발생시키는 대신 null을 반환하고, null이 아니라면 정상적으로 메서드를 호출합니다.
기존 코드와 비교하면 다음과 같습니다.
string result = instance == null ? null : instance.Method();
null 조건부 연산자를 적용하면 아래처럼 간단해집니다.
string result = instance?.Method();
사용 예제
using System;
class Program{
static void Main(){
string foo = null;
string answer = foo?.ToString();
Console.WriteLine(answer); // 아무것도 출력되지 않음 (null)
}
}전체 통합 예제
세 가지 연산자를 하나의 프로그램에서 함께 확인해 보겠습니다.
using System;
class Program{
static void Main(){
string input = null;
string choice = input ?? "default_choice";
Console.WriteLine(choice); // default_choice 출력
string finalChoice = choice ?? "not_chosen";
Console.WriteLine(finalChoice); // default_choice 출력
string foo = null;
string answer = foo?.ToString();
Console.WriteLine(answer); // 아무것도 출력되지 않음 (null)
}
}실행 결과
default_choice default_choice
마무리
C#의 null 관련 연산자 세 가지를 정리하면 다음과 같습니다.
- ?? (null 병합 연산자): 값이 null이면 기본값으로 대체
- ??= (null 병합 할당 연산자): 값이 null일 때만 기본값을 할당
- ?. (null 조건부 연산자): null 여부를 검사한 후 안전하게 멤버 접근
이 연산자들을 적극 활용하면 null 검사 코드를 크게 줄이고, 예외 발생 가능성을 낮추며, 더 깔끔하고 유지보수하기 좋은 C# 코드를 작성할 수 있습니다.