
C#에 존재하는 모든 클래스들은 상속받는다고 쓰지 않아도 Object 타입에 상속 받고 있다.
모든 타입의 조상
모든 값 타입(int,double 등등) 참조 형식(enum, struct) 등이 Object 클래스를 상속받는다.
이 Object 타입은 4개의 메서드를 가지고있다. ToSring, GetType, Equals, GetHashCode
C#에서는 모든 데이터 형식이 Object를 '상속' 받도록 구조가 짜여져 있기 때문이다.
Object는 모든 타입의 부모이기에 모두를 담을 수 있고, 이를 통해서 object 배열 같은 것을 선언하면 다양하게 타입을 담아두며 편리하게 사용할 수 있다.
하지만 이렇게 편리하다고 마구잡이로 사용하게 되면 메모리 낭비가 심하기 때문에 박싱과 언박싱 개념을 이해해야한다.
📌 박싱을 통해 값 형식(int, double, struct 등)을 'object' 타입이나 다른 인터페이스를 구현한 참조 형식으로 변환할 수 있다.
📌 박싱은 값 형식을 힙(heap) 메모리에 할당하여야 하므로 성능에 영향을 줄 수 있다. 박싱된 값은 가비지 컬렉션 대상이 되며, unboxing이 발생할때 추가적으로 오버헤드가 발생할 수도 있다.
오버헤드: 어떤 처리를 하기 위해 들어가는 간접적인 처리 시간/메모리 등을 말한다.
📌 C#에서는 박싱을 암시적으로 수행할 수 있으며, 명시적으로도 수행할 수 있다.
int i = 10; // 값 형식 변수 선언
object obj = i; // 암시적 박싱: int를 object로 변환
Console.WriteLine(obj); // 출력 결과: 10
// 명시적 박싱
double d = 3.14;
object obj2 = (object)d; // double을 object로 명시적으로 변환
// 배열에서의 박싱
int[] array = { 1, 2, 3 };
object boxedArray = array; // 배열을 object로 박싱
// 박싱된 값의 언박싱
int j = (int)obj; // object를 int로 언박싱
Console.WriteLine(j); // 출력 결과: 10
📌 언박싱은 박싱된 객체에서 저장된 값을 다시 해당 값 형식으로 변환하여 사용할 수 있도록 한다.
📌 C#에서 언박싱은 명시적으로만 가능하다. 즉, 'object' 타입 변수를 명시적으로 원래의 값 형식으로 캐스트해야 한다.
📌 언박싱은 힙(heap)에서 스택(stack)으로 이동시키는 작업이므로 추가적인 오버헤드가 발생할 수 있다.
object obj = 10; // int를 object로 암시적 박싱
int i = (int)obj; // object에서 int로 명시적 언박싱
Console.WriteLine(i); // 출력 결과: 10
// 박싱된 배열에서의 언박싱
object boxedArray = new int[] { 1, 2, 3 };
int[] array = (int[])boxedArray; // object에서 int[]로 명시적 언박싱
foreach (int num in array)
{
Console.WriteLine(num); // 출력 결과: 1, 2, 3
}