-
19장. Null 값 타입CLR Via C# 2022. 6. 21. 20:33
값 타입의 변수에는 절대로 null을 대입할 수 없다.
그래서 null을 대입할 수 있는 값 타입으로 System.Nullable<>을 제공한다.
이 클래스는 값 타입도 null이 될 수 있도록 일부 정보를 캡슐화하고 있다. Nullable 그 자체는 여전히 값 타입이므로 인스턴스의 크기는 크지 않다. 값 타입이라는 것은 이 인스턴스가 스택에 위치할 수 있음을 의미하며, 구체적으로 그 크기는 원래 타입의 인스턴스의 크기에 겨우 Boolean 필드의 크기 정도만 더해진 정도다. 다음은 Nullable을 사용한 코드이다.
Nullable<Int32> x = 5; Nullable<Int32> y = null; Console.WriteLine("x: HasValue={0}, Value={1}", x.HasValue, x.Value); Console.WriteLine("y: HasValue={0}, Value={1}", y.HasValue, y.GetValueOrDefault()); // 이 코드를 컴파일하고 실행하면, 다음과 같은 결과가 나타나게 된다. // x: HasValue=True, Value=5 // x: HasValue=False, Value=0C#의 Nullable 값 타입에 대한 지원
C#에서는 Nullable 값 타입을 ?를 붙여 편리하게 사용 가능하다.
Int32? x = 5; Int32? y = null;또한 Nullable 값 타입의 인스턴스에 대해 변환과 캐스팅까지도 지원하고, 연산자도 지원한다.
Int32? a = 5; Int32 b = (Int)a; Double? c = 5; Double? d = a; Int32? e = null; a++; // a = 6 e = -e; // e = null a = a + 3; // a = 9 e = e * 3; // e = nullC#의 Null 결합 연산자
C#은 Null 결합 연산자라고 부르는 연산자를 지원하는데 두 개의 오퍼랜드를 필요로 한다. 만약 왼쪽에 오는 오퍼랜드가 null이 아니라면 왼쪽의 값이 반환된다. 만약 null이면 오른쪽의 오퍼랜드가 반환된다.
Int32? b = null; Int32 x = b ?? 123; Console.WriteLine(x); // "123" String filename = GetFilename() ?? "Untitled";C#에서 Nullable 값 타입의 특별한 기능
Nullable 값 타입에 대한 박싱
Nullable 인스턴스를 박싱해야 할 경우, 해당 인스턴스의 상태가 null인지 확인하며, 만약 그렇다면 CLR은 실제로 아무것도 박싱하지 않은 채로, null 참조를 반환한다. 만약 null 상태가 아니라면, CLR은 실제 값을 꺼내서 원래대로 박싱을 수행한다.
Nullable 값 타입의 언박싱
CLR은 박싱된 값 타입 T를 언박싱하거나 Nullable로 변환하는 것을 허용한다. 만약 박싱된 값 타입의 참조가 null이면 Nullable 타입으로 언박싱하려 할 때, null 상태로 설정하게 된다.
Nullable 값 타입에 대한 GetType 메서드 호출
Nullable 객체의 GetType 메서드를 호출하면 CLR은 해당 객체의 타입이 Nullable 타입이 아니라 T 타입이라고 결과를 바꿔서 돌려준다.
Nullable 값 타입을 통한 인터페이스 메서드를 호출
코드로 간단히 보면 다음과 같은 것이 가능하다.
Int32? n = 5; Int32 result = ((IComparable) n).CompareTo(5); // 다음과 같은 코드를 위와 같이 간단히 사용 가능하다. // Int32 result = ((IComparable) (Int32) n).CompareTo(5); Console.WriteLine(result); // 0'CLR Via C#' 카테고리의 다른 글
21장. 관리 힙과 가비지 수집 (0) 2022.07.13 20장. 예외와 상태 관리 (0) 2022.06.30 18장. 사용자 정의 특성 (0) 2022.03.16 17장. 델리게이트 (0) 2022.03.09 16장. 배열 (0) 2022.02.28