티스토리 뷰

[C#] 박싱(Boxing)과 언박싱(Unboxing)


이번 글에서는 C#에서 데이터 타입을 변경하는데 사용되는 박싱과 언박싱에 대해서 알아보도록 하겠습니다.


C#은 2가지의 타입(Reference, Value)을 제공합니다. 

  • 값 형식 : structs, 열거형, 숫자형식, bool 등
  • 참조 형식 : class, interface, delegate, dynamic, object, string 등


C#의 모든 타입의 최상위 타입은 Reference 타입은 System.Object입니다.  그렇다면 참조(Reference) 타입에서 값(Value) 타입으로 전환을 할려면 어떻게 할까요? 닷넷 프레임워크에서는 박싱, 언박싱이라는 방식을 통해서 두개의 데이터형 사이를 변환할 수 있습니다. 


1) 박싱(Boxing)이란?


Value 타입의 객체를 타입이 구체적으로 정의되어 있지 않는 Reference 타입의 객체 내부로 포함하여 Reference 타입으로 사용이 가능하게끔 해주는 기능


박싱을 수행하게 되면 힙상에 새로운 참조 타입의 객체가 생성이 되고, 값 타입 내부의 값이 참조 타입의 객체 내부에 복사됩니다. 

아래의 그림을 통해서 스택에서 힙 메모리로 참조 객체가 생성되는 모습을 볼 수 있습니다. 


int i = 123;

object o = i; // c#에서는 자동 형변환이 가능




박싱을 고려할 때 아래의 코드를 생각해 봐야합니다. 아래의 코드는 콘솔창에 Test Code : 10020을 출력하기 위한 코드입니다. 


Console.WriteLine("Test Code : {0}", 10020);


이 코드를 수행하면 컴파일러는 WriteLIne 함수의 인자로 변환할 때 WriteLIne은 항상 Object 형만 받기 때문에 10020이 object형으로 박싱됩니다. 


// WriteLine 입력시

int i = 10020

object o = i; // boxing


그리고 WriteLIne을 수행하기 위해 Object 형을 String으로 변환하기 위해서 아래의 코드가 수행이 됩니다. 


// WriteLine 내부 함수에서 UnBoxing 및 ToString() 적용

int i = (int)o; // Unboxing

string output = i.ToString();


즉 WriteLine에 숫자형을 문자열로 변경하기 위해서 총 박싱 1회, 언박싱 1회, ToString() 함수 호출 1회가 발생을 합니다. 이러한 컴파일러의 수행 성능을 보완하기 위해서 사용자는 아래와 같은 코드를 고려해야합니다. 


Console.WriteLine("Test Code : {0}", 10020.ToString());


2) 언박싱(Unboxing)이란?


언박싱은 박싱이 되어 있는 참조 타입의 객체 복사본을 다시 값 타입으로 돌리면서 다시 값 타입을 복사하여 전달하는 과정을 말합니다.


int i = 123;

object o = i;

int j = (int)i;


위의 코드는 박싱된 코드를 언박싱하는 과정을 나타냅니다. 박싱된 i의 객체에 대해서 객체의 인스턴스가 지정한 값 형식이 박싱된 값인지를 확인한 뒤에 인스턴스의 값을 값 형식 변수에 복사합니다. 



참고 : Collection을 사용할 때 언박싱을 피하기 위해서는 Collection에 들어가는 Struct를 Interface를 통해서 상속을 받는다면 인터페이스를 상속받은 Struct를 변환할 때 언박싱이 일어나지 않습니다. 혹은 Generic을 사용하면 됩니다. 


이글이 도움이 되셨나요?

그렇다면 아래의 그림을 클릭해주세요.


댓글