ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • nullable
    @ 16. 1 ~ 17. 1/C# 2016. 11. 19. 14:42

    Nullable 타입의 박싱/언박싱

    박싱과 언박싱에 대한 이야기를 나누어 보기 전에 null 값의 비교에 대해서 살펴보도록 하겠다. Nullable 타입의 비교는 HasValue 속성을 직접 이용할 수도 있고 == 연산자를 이용할 수도 있다. 
     

    DateTime? birthday;
    If(birthday==null)
    If(birthday.HasValue)

     
    그리고 Nullable<T> 타입은 다음과 같이 값뿐만 아니라 null을 대입할 수 있다는 것을 볼 수 있다. 
     

    DateTime? birthday;
    birthday = null;
    birthday = new DateTime(1938,03,21);

     
    하지만 이 코드를 개념상으로 접근한다면 상당히 혼란스러운 부분일 수 있다. 그래서 내부적인 동작을 IL로 확인해 본 결과 birthday = null 코드는 DateTime? 생성하여 대입하는 것을 볼 수 있었고, birthday = new DateTime(1938,03,21); 코드는 DateTime의 일반 생성자를 호출하고 그 결과를 바로 Nullable<DateTime>으로 다시 감싼 후에 전달하는 것을 볼 수 있었다. 
     
    C#에서는 박싱/언박싱 작업이 빈번하게 일어나게 된다. 박싱이란 값 타입을 참조 타입에 대입하는 것을 의미한다. 하지만 값 타입을 어떻게 참조 타입에 넣을 수 있을까? 논리적으로 볼 때 불가능한 부분인 것이다. 하지만 C#의 값 타입은 System.Object 객체로 변환할 수 있게 설계되었기 때문에 자신을 참조타입으로 변환하는 것이 가능하다. 참조타입에 값 타입을 대입하면 스택의 값을 객체에 복사한 후 그 객체는 힙에 저장되게 된다. 언박싱은 그 반대의 작업이 일어난다고 볼 수 있다. 


    [그림]


    그렇다면 nullable 타입은 값 타입일까? 참조 타입일까? C#에서는 nullable 타입을 값 타입으로 구분하고 있다. 때문에 참조 타입에 대입한다면 박싱, 언박싱이 일어난다는 사실을 알아두어야 한다.
    다음은 nullable 타입의 박싱과 언박싱에 대한 예를 보여주고 있다.
     

    Int? nullable = 5;
     
    //값이 있는 null 박싱
    object boxed = nullable;
    Console.WriteLine(boxed.GetType());
     
    //일반 변수로 언박싱
    int normal = (int)boxed;
    Console.WriteLine(normal);
     
    //null 변수로 언박싱
    nullable = (int?)boxed;
    Console.WriteLine(nullable);
     
    //값이 없는 null 박싱
    nullable = new int?();
    boxed = nullable;
    Console.WriteLine(boxed == null);
     
    //null 변수로 언박싱
    nullable = (int?)boxed;
    Console.WriteLine(nullable.HasValue);

    [박싱 언박싱 예제]
     
    이 코드를 실행하면 다음과 같은 결과를 볼 수 있다. 

    '@ 16. 1 ~ 17. 1 > C#' 카테고리의 다른 글

    as 연산자 / yield  (0) 2016.12.08
    가비지 컬렉터 가비지 컬렉션  (0) 2016.11.19
    C#AVL 트리  (0) 2016.11.18
    델리게이트, 이벤트 - 1  (0) 2016.11.18
    object 란? boxing unboxing!  (0) 2016.11.18
Designed by Tistory.