ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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=0

    C#의 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 = null

    C#의 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
Designed by Tistory.