본문 바로가기
Programming Language/C#

[C#] 박싱과 언박싱

by dbxxrud 2019. 4. 28.

 

박싱(Boxing) - 값 형식을 참조 형식으로 변환하는 것을 말하며 스택에 있는 데이터가 힙으로 복사

 

언박싱(Unboxing) - 참조 형식을 값 형식으로 변환하는 것을 말하며 힙에 있는 데이터가 스택에 복사

 

값 형식의 자료는 스택 메모리 영역에, 참조 형식의 자료는 힙 메모리 영역에 할당이 된다. object 형식은 참조 형식 이기 때문에 힙에 데이터를 할당. int와 double 은 값 형식이기 때문에 스택에 데이터를 할당하지만 값 형식의 데이터 형식도 object 형식 객체에 담을 수 있다. 이처럼 object 형식에 값 형식 데이터를 할당하려고 하면 object 형식은 자동으로 박싱을 수행해서 데이터를 힙에 할당한다.

 

 

박싱

 

박싱

 

언박싱

 

a는 20이 박싱 되어 저장되어 있는 힙을 참조하고 있다. b는 a가 참조하고 있는 메모리로부터 값을 복사한다.

또한 언박싱은 명시적으로 형 변환을 해주어야 한다.

 

언박싱

  • 언박싱은 박싱 한 객체만 가능

또한 언박싱은 박싱 한 객체에 대해서만 가능하다 모든 객체가 값 형식으로 언박싱 될 수는 없다

이전에 값 형식을 박싱 하여 생성된 객체에 한해서 언박싱이 가능하다. 박싱이 일어나지 않은 객체에 대한 언박싱 은 NullReferenceException 이 발생한다.

 

  • 박싱 하기 전 형식을 준수해야 한다

형 변환 시 short 타입을 더 큰 자료형인 int 타입으로 변환하는 것은 문제가 없지만, short 타입을 박싱 한 객체를 int타입으로 언박싱 하는 것은 안된다. InvalidCastException 이 발생한다.

 

 

성능

 

박싱과 언박싱의 성능에 대한 MSDN 을살펴보자면, 값 형식을 박싱 할 때는 완전히 새로운 개체가 만들어져야 하며, 이러한 작업에는 할당 작업보다 최대 20배의 시간이 걸린다. 언박싱을 할 때는 캐스팅 과정에서 할당 작업보다 4배의 시간이 걸릴 수 있다.

 

 

 

 

그렇다면 왜 사용할까?

 

사용상의 편의성 때문이다. C#의 모든 자료형은 System.object를 상속받기 때문에 제약사 항의 자유를 가질 수 있다.

 

 

예제

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using System
     
namespace BoxingUnboxing 
    class MainApp 
    { 
        static void Main(string[] args) 
        { 
            int a = 123;                 
            object b = (object)a;   // a의 담긴 값을 박싱해서 힙에 저장 
            int c = (int)b;         // b에 담긴 값을 언박싱해서 스택에 저장 
 
            Console.WriteLine(a);    
            Console.WriteLine(b); 
            Console.WriteLine(c); 
     
            double x = 3.1414213
            object y = x;           // x에 담긴 값을 박싱해서 힙에 저장 
            double z = (double)y;   // y에 담긴 값을 언박싱해서 스택에 저장 
     
            Console.WriteLine(x); 
            Console.WriteLine(y); 
            Console.WriteLine(z); 
        } 
    } 
 
 
 

'Programming Language > C#' 카테고리의 다른 글

[C#] Null 병합 연산자 (Null-Coalescing Operator)  (0) 2019.04.28
[C#] 널 조건부 연산자 (Null-conditional operator)  (0) 2019.04.28
[C#] var  (0) 2019.04.28
[C#] Nullable 형식  (0) 2019.04.28
[C#] object 형식  (0) 2019.04.28