* 정의
null을 가질 수 있도록 하기 위해 정의된 타입이다.
처음에는 값 타입에서 비워진 상태(null)를 가질 수 있도록 하기 위해서 사용되었다.
C# 8.0부터는 참조 타입에서도 null을 가질 수 있는 지 명시하도록 하고있다. 명시하지 않으면 경고 메시지가 출력된다.
* 동작 방식
null 값을 가질 수 있도록 하기 위해서 데이터 타입 뒤에 '?'를 붙여주면 된다.
int? value1 = null;
float? value2 = null;
- Nullable 클래스와 값 타입
값 타입에 ? 를 붙였을 때 어떤 일이 발생하는 지 조금 자세히 보기 위해 ildasm 툴로 확인해보면 다음과 같은 결과가 나온다.

값 타입에 System.Nullable<> 을 씌워서 사용하게 된다. System.Nullable 역시 struct이기 때문에 값 타입이다.
Nullable<> 클래스의 Value라는 프로퍼티를 통해서 실제 값에 접근할 수 있다. 그리고 사용 전에는 항상 HasValue라는 프로퍼티나 'null == myVar'(HasValue와 동일하다.) 이런 식으로 null 체크를 하고 사용해야한다. 만약 null 체크를 하지 않고 사용하려고하면 컴파일러가 경고 메시지를 던진다. 그럼에도 사용한다면 런타임에서 크래시가 발생한다.

다음과 같이 변경해서 사용한다.

- Nullable 참조 타입(Nullable Reference Type, NRT)
원래는 참조 타입에 대해 기본 값을 nullable로 정의하고 있었지만(추가 코드 없이 그냥 null로 할당 가능했지만) C#8.0 부터는 기본 값을 Non-nullable로 정의하고 있다.(명시적으로 지정하지 않으면 변수가 null이 아니라고 가정한다.)
// MS에서 NullReferenceException를 고치기 위해 그렇게 만들었다.
만약 명시적으로 작성하지 않고 null을 할당하면 경고 메시지가 나온다.

다음과 같이 사용해야한다.

NRT에서는 두 개의 연산자를 제공한다.
- ? : 값 타입과 동일한 구문이다. 해당 객체가 널이될 수 있다고 컴파일러에게 알려준다.
- ! : null forgiving operator으로 컴파일러에게 해당 값이 null이 아니라는 것을 알려준다. 프로그래머가 null 값이 아님을 확실하게 알고 있지만 컴파일러가 분석을 잘 못해서 null 값이라고 판단하는 경우 사용한다. 이를 사용하면 컴파일러는 더이상 해당 변수를 체크하지 않는다. 판단을 잘못하게 되면 런타임에 null이 발생할 수도 있기 때문에 신중하게 사용해야한다.
다음 글에서 조금 더 자세한 정보를 확인할 수 있다.
https://blog.miguelbernard.com/c-8-0-nullable-reference-types-are-here
C# 8.0 Nullable Reference types are here!
C# 8.0 just rolled out with a lot of new features. One of the most important ones is the support of nullable reference types (NRT)
blog.miguelbernard.com
'C#' 카테고리의 다른 글
| [C#] object (0) | 2022.06.28 |
|---|---|
| [C#] string vs StringBuilder (0) | 2022.06.28 |
| [C#] 값 타입과 참조 타입(Value type, Reference type) (0) | 2022.06.28 |
| [C#] .NET (0) | 2022.06.28 |
| [C#] abstract, sealed (0) | 2022.04.08 |