-
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