C#에서 언박싱(Unboxing)이란?
C#에서 박싱(Boxing)은 암시적으로(자동으로) 수행되는 반면, 언박싱(Unboxing)은 명시적으로 수행해야 합니다.
언박싱이란 박싱을 통해 생성된 참조 타입(object) 객체를 다시 원래의 값 타입(value type)으로 되돌리는 명시적 형변환을 의미합니다. 즉, 힙(heap) 영역에 저장된 객체에서 값을 꺼내어 스택(stack)의 값 타입 변수에 할당하는 과정입니다.
박싱과 언박싱의 기본 예제
다음은 C#에서 int 타입 변수를 object로 박싱한 후, 다시 언박싱하는 기본적인 예제입니다.
// int 값 타입 변수 int x = 30; // 박싱: 값 타입 → 참조 타입 (암시적 변환) object obj = x; // 언박싱: 참조 타입 → 값 타입 (명시적 변환) int unboxInt = (int) obj;
위 코드에서 object obj = x; 부분이 박싱으로, 컴파일러가 자동으로 처리합니다. 반면 (int) obj처럼 반드시 캐스트 연산자를 사용하여 명시적으로 변환해야 하는 것이 언박싱입니다.
ArrayList를 활용한 언박싱 예제
컬렉션 클래스인 ArrayList는 object 타입으로 요소를 저장하므로, 값 타입을 추가할 때 박싱이 발생하고, 다시 꺼낼 때 언박싱이 필요합니다.
int x = 5; ArrayList arrList = new ArrayList(); // 박싱: ArrayList에 값 타입 추가 시 자동으로 박싱됨 arrList.Add(x); // 언박싱: object를 다시 int로 명시적 변환 int y = (int) arrList[0];
언박싱 시 주의사항
언박싱을 사용할 때는 몇 가지 주의할 점이 있습니다.
- 정확한 타입 일치 필요: 박싱된 값과 언박싱하려는 타입이 일치하지 않으면
InvalidCastException이 발생합니다. 예를 들어 int로 박싱된 값을 long으로 언박싱하면 런타임 오류가 발생합니다. - null 값 언박싱 불가: null 참조를 값 타입으로 언박싱하려 하면
NullReferenceException이 발생합니다. - 성능 오버헤드: 박싱과 언박싱은 힙 메모리 할당과 복사 작업을 동반하므로, 빈번하게 사용되면 성능 저하의 원인이 됩니다. 이를 피하려면 제네릭 컬렉션(List<T> 등)을 사용하는 것이 좋습니다.
정리
박싱은 값 타입을 object 타입으로 변환하는 암시적 과정이고, 언박싱은 그 object를 다시 값 타입으로 변환하는 명시적 과정입니다. 두 연산 모두 내부적으로 새로운 메모리 할당과 데이터 복사가 일어나기 때문에, 성능이 중요한 코드에서는 제네릭(Generic)을 활용해 박싱/언박싱을 최소화하는 것이 바람직합니다.