[C#] Null-operator(?., ?[], ??, ??=)

1. Null-conditional operator

C#에서 제공하는 연산자 중 하나인 null-conditional operator은 참조하려는 정보가 null인지 미리 체크 후 이에 맞는 값을 반환한다.

 

member 혹은 element에 접근할 때 사용가능 하며 각각 ?., ?[]로 쓸 수 있다.

 

1. 만약 a가 null이면, a?.x 혹은 a?[x]의 반환 값은 null이다.

2. 만약 a가 null이 아니면, a.?x 혹은 a?[x]의 반환 값은 각각 a.x, a[x]와 동일하다.

 

C#을 사용하는 유니티로 간단한 예제를 아래와 같이 작성해볼 수 있다.

using UnityEngine;
using UnityEngine.UI;

public class Test : MonoBehaviour
{
    public GameObject testObject;
    private Image testImage;
    void Init(){
        testImage = testObject?.GetComponent<Image>();
    }
}

 

만약 testObject가 null이면 testImage에는 null이 들어간다.

만약 testObject가 null이 아니고 Image 컴포넌트를 가지고 있으면, testImage에는 해당 Image 컴포넌트가 들어간다.

 

Null-conditional의 주의할 점은, ?., ?[] 연산은 exception을 그대로 throw 한다는 점이다.

 

예를 들어, 배열 a에서 범위 바깥에 해당하는 x를 참조한다고 해보자.

a[x]는 IndexOutOfRangeException을 반환할 것이다.

만약 a?[x]라고 쓰고 a가 null이 아니어도, 여전히 IndexOutOfRange를 반환한다.

 

Null-conditional operator의 또 다른 특징은 short-circuting이다.

이는 && 와 || 연산자도 가지는 동일한 특징인데, 앞의 결과에 따라 뒤의 내용은 실행하지 않는다.

 

예를 들어, a, b, c가 존재하여 다음과 같이 작성되었다고 하자.

a?.b?.c

 

만약 a가 null이면 뒤의 b, c는 실행되지 않고 바로 null을 반환한다.

만약 a 또는 b가 null이면 뒤의 c는 실행되지 않고 바로 null을 반환한다.

 

2. Null-coalescing operators

Null-coalescing operator는 ??, ??= 연산자가 있으며 연산자 왼쪽에 오는 값이 null인지 체크하여 이에 맞는 값을 반환한다.

 

?? 연산자는 a ?? b 이런 식으로 작성하며, 왼쪽 값(a)이 null이면 오른쪽 값(b)를 반환하는 연산이다.

using UnityEngine;
using UnityEngine.UI;

public class Test : MonoBehaviour
{
    public GameObject testObject;
    public Image testImage2;
    private Image testImage;
    void Init(){
        testImage = (GetComponent<Image>() ?? testImage2);
    }
}

 

위 코드에서는 Test에서 Image가 null이면, testImage2를 할당해준다.

 

??= 연산자는 a ??= b 이런 식으로 작성하며, 왼쪽 값(a)이 null이면 오른쪽 값(b)를 대입하는 연산이다.

이때, 왼쪽에 오는 값은 반드시 variable, property, 또는 indexer 이여야 한다.

 

using UnityEngine;
using UnityEngine.UI;

public class Test : MonoBehaviour
{
    public GameObject testObject;
    public Image testImage2;
    private Image testImage;
    void Init(){
    	testImage = GetComponent<Image>();
        testImage ??= testImage2;
    }
}

 

위 코드에서는 testImage가 null이면 testImage2를 넣게된다.

 

??= 연산자의 장점으로 다음과 같이 null 체크하는 코드를 간결하게 작성할 수 있다.

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

// ??= operator
variable ??= value;

 

References

더보기