`??`와 `??=` 연산자 — null 병합 연산자

????= 연산자 — null 병합 연산자

값이 비어 있을 때(정확히는 null일 때) 쓸 기본값을 미리 정해 두고 싶을 때가 많죠. C#의 null 병합 연산자 ????=가 바로 그 자리를 담당해요. 왼쪽 피연산자가 null이 아니면 그 값을 그대로 돌려주고, null이면 오른쪽 피연산자를 계산해 그 결과를 돌려줍니다. 여기서 중요한 건, 왼쪽 피연산자가 null이 아니면 오른쪽은 아예 계산하지 않는다는 점이에요. null 병합 대입 연산자 ??=는 왼쪽 피연산자가 null일 때만 오른쪽 피연산자 값을 왼쪽에 넣어 주고, 왼쪽이 null이 아니면 오른쪽을 계산하지 않습니다.

:::code language="csharp" source="snippets/shared/NullCoalescingOperator.cs" id="Assignment":::

??= 연산자의 왼쪽 피연산자는 변수, 속성, 또는 인덱서 요소여야 해요.

[!INCLUDEcsharp-version-note]

????= 연산자의 왼쪽 피연산자 타입은 nullable이 아닌 값 타입(non-nullable value type)일 수 없어요. 특히 제약 없는 타입 매개변수(unconstrained type parameter)에도 null 병합 연산자를 쓸 수 있습니다.

:::code language="csharp" source="snippets/shared/NullCoalescingOperator.cs" id="UnconstrainedType":::

null 병합 연산자는 오른쪽 결합(right-associative)이에요. 즉 다음과 같은 표현식은

a ?? b ?? c
d ??= e ??= f

이렇게 계산됩니다.

a ?? (b ?? c)
d ??= (e ??= f)

본문

????= 연산자는 이런 상황에서 특히 유용해요.

  • null 조건부 연산자 ?.?[]를 쓴 표현식에서는 결과가 null일 때 대신 계산할 대체 표현을 ??로 지정해 줄 수 있어요.

    :::code language="csharp" source="snippets/shared/NullCoalescingOperator.cs" id="WithNullConditional":::

  • nullable 값 타입을 다루면서 기반 값 타입의 값이 필요할 때는, nullable 값이 null이라면 제공할 값을 ??로 지정해요.

    :::code language="csharp" source="snippets/shared/NullCoalescingOperator.cs" id="WithNullableTypes":::

    nullable 값이 null일 때 기반 값 타입의 기본값을 쓰고 싶다면 xref:System.Nullable`1.GetValueOrDefault?displayProperty=nameWithType 메서드를 이용하면 돼요.

  • 인자 검사 코드를 더 간결하게 만들고 싶으면 ?? 오른쪽 피연산자로 throw 표현식을 쓰세요.

    :::code language="csharp" source="snippets/shared/NullCoalescingOperator.cs" id="WithThrowExpression":::

    위 예시는 식 본문 멤버로 속성을 정의하는 방법도 함께 보여 주고 있어요.

  • ??=는 다음과 같은 코드를 대신해 줘요.

    if (variable is null)
    {
        variable = expression;
    }
    

    이 코드를 이렇게 바꿔 쓸 수 있습니다.

    variable ??= expression;
    

더 알아보기

????= 연산자는 오버로드할 수 없어요.

?? 연산자에 대한 자세한 내용은 C# 언어 사양null 병합 연산자 섹션을, ??= 연산자는 같은 사양의 복합 대입 섹션을 참고하세요.

출처: null-coalescing operators