0Pricing
C# Academy · 강의

null 조건부 및 null 병합 연산자

?., ?[], ??, ??=를 조합해 장황한 null 검사 없이 간결하고 null에 안전한 코드를 작성합니다.

null 조건부 및 null 병합 연산자은(는) CoddyKit의 무료 C# Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 C# Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. C# Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

null 안전 코드 패턴

C#은 null 값을 간결하게 처리하는 세 가지 전용 연산자를 제공합니다. null 조건부(?., ?[]), null 병합(??), null 병합 할당(??=) 연산자입니다. 이들을 함께 사용하면 장황한 null 확인 상용구 코드 대부분을 제거할 수 있습니다.

null 조건부 연산자: ?.

?.는 왼쪽이 null이면 NullReferenceException을 발생시키는 대신 null로 단락됩니다. 따라서 결과 형식은 null 허용 형식이 됩니다.

User? user = GetUser(id);

// Without ?.:
string? name = null;
if (user != null) name = user.Name;

// With ?.:
string? name2 = user?.Name;

// Chained:
string? city = user?.Address?.City;

// Method call:
string? upper = user?.Name?.ToUpper();

인덱서와 함께 사용하는 null 조건부 연산자: ?[]

?[]은 null 조건부 인덱스 연산자입니다. 컬렉션 자체가 null일 수 있을 때 배열 또는 컬렉션 요소에 안전하게 액세스할 수 있습니다.

List<string>? tags = product?.Tags;

// Safe index access
string? firstTag = tags?[0];

// Null-conditional LINQ
int? count = tags?.Count;
bool? hasItems = tags?.Any();

// With methods:
string? joined = tags?.FirstOrDefault()?.ToUpper();

null 병합 연산자: ??

??는 왼쪽 피연산자가 null이 아니면 왼쪽 피연산자를 반환하고, 그렇지 않으면 오른쪽 피연산자(대체 값)를 반환합니다. x != null ? x : fallback을 간결하게 대체하는 연산자입니다.

string? name = GetName();

// Without ??:
string display = name != null ? name : "Anonymous";

// With ??:
string display2 = name ?? "Anonymous";

// Chaining ?? for multiple fallbacks:
string result = primary ?? secondary ?? tertiary ?? "Default";

// Combining with ?.
string city = user?.Address?.City ?? "Unknown City";

널 병합 대입: ??=

??=는 변수가 현재 null일 때만 오른쪽 값을 변수에 대입합니다. 지연 초기화 패턴에 안성맞춤입니다.

// Lazy initialization
private List<string>? _cache;

public List<string> GetCache()
{
    _cache ??= new List<string>(); // only assigns if null
    return _cache;
}

// Equivalent to:
// if (_cache is null) _cache = new List<string>();

// In-place:
string? name = null;
name ??= "Default";
Console.WriteLine(name); // "Default"

이벤트에서 ?. 사용하기

널 조건부 연산자는 이벤트를 호출할 때 표준적인 스레드 안전 방식입니다. 별도의 null 확인과 호출에서 발생하는 경쟁 상태를 방지합니다.

public event EventHandler<DataEventArgs>? DataReceived;

// Thread-safe event invocation:
DataReceived?.Invoke(this, new DataEventArgs(data));

// This is equivalent to:
var handler = DataReceived;
if (handler != null) handler(this, new DataEventArgs(data));
// (local copy avoids race condition between check and invoke)

복합 연결 예제

연산자를 조합하면 깊게 중첩된 객체 그래프를 깔끔하고 읽기 쉽게 null 안전하게 탐색할 수 있습니다.

var order = GetOrder(id);

// Deeply nested with fallbacks:
string countryCode = order
    ?.Customer
    ?.ShippingAddress
    ?.Country
    ?.Code
    ?? "US";

// Collection safe access:
decimal firstLineTotal = order
    ?.Lines
    ?.FirstOrDefault()
    ?.Total
    ?? 0m;

// Method chain:
string? trackingUpper = order?.TrackingNumber?.ToUpper().Trim();

LINQ에서 널 조건부 연산자

널 조건부 연산자는 LINQ와 원활하게 함께 사용할 수 있으므로, null일 수 있는 컬렉션이나 속성을 안전하게 질의할 수 있습니다.

List<Order>? orders = customer?.Orders;

// Safe LINQ on a nullable collection:
var totalRevenue = orders?.Sum(o => o.Total) ?? 0m;
var pendingCount = orders?.Count(o => o.Status == OrderStatus.Pending) ?? 0;
var latest       = orders?.MaxBy(o => o.PlacedAt)?.Id;

ThrowIfNull을 사용한 null 검사

null이 아니어야 하는 매개 변수에는 ArgumentNullException.ThrowIfNull() (.NET 6+)을 사용하면 메서드 진입 시 간결하고 설명적인 유효성 검사를 수행할 수 있습니다.

public void ProcessOrder(Order order, Customer customer)
{
    ArgumentNullException.ThrowIfNull(order);
    ArgumentNullException.ThrowIfNull(customer);

    // From this point, compiler knows both are non-null
    Console.WriteLine(order.Id);
    Console.WriteLine(customer.Name);
}

// .NET 7+: ArgumentException.ThrowIfNullOrEmpty
void Save(string name)
{
    ArgumentException.ThrowIfNullOrWhiteSpace(name);
    // name is guaranteed non-empty
}

Switch의 null 아님 패턴

is not null 및 is { }를 사용한 패턴 매칭은 특히 switch 식에서 깔끔하게 null을 확인할 수 있는 패턴을 제공합니다.

string Describe(object? obj) => obj switch
{
    null                          => "nothing",
    string s when s.Length == 0  => "empty string",
    string s                      => $"string: {s}",
    int i                         => $"integer: {i}",
    { }                           => $"object: {obj.GetType().Name}"
};

// is not null in if statements:
if (order is not null && order.Customer is { Name: var name })
    Console.WriteLine(name);

빠른 확인

user?.Name ?? "Anonymous" 표현식은 user가 null일 때 무엇을 반환합니까?

널 조건부 및 널 병합 요약

핵심 요점:

  • ?.: 안전한 멤버 접근 — 수신자가 null이면 예외를 throw하는 대신 null을 반환합니다
  • ?[]: null일 수 있는 컬렉션의 안전한 인덱스 접근
  • ??: 왼쪽 피연산자가 null일 때 사용할 대체 값
  • ??=: null일 때만 대입 — 지연 초기화에 안성맞춤입니다
  • 다음처럼 연결할 수 있습니다: a?.B?.C ?? defaultVal를 사용한 깊은 null 안전 탐색
  • 매개 변수 유효성 검사를 위한 ArgumentNullException.ThrowIfNull() 가드

자주 묻는 질문

“null 조건부 및 null 병합 연산자” 강의는 무료인가요?

네 — “null 조건부 및 null 병합 연산자” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 C# Academy 강의 전체를 잠금 해제할 수 있습니다. C# Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“null 조건부 및 null 병합 연산자”에서 뭘 배우나요?

?., ?[], ??, ??=를 조합해 장황한 null 검사 없이 간결하고 null에 안전한 코드를 작성합니다. 브라우저에서 직접 실행하는 실습 코드로 C# Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

C# Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 C# Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.

“null 조건부 및 null 병합 연산자” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 C# Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 C# Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. NRT 활성화와 이해
  2. 주석: ?, !, MaybeNull과 NotNull
  3. null 조건부 및 null 병합 연산자
  4. 코드베이스를 NRT로 마이그레이션하기
← C# Academy(으)로 돌아가기