[유니티 / C#] 박싱(Boxing), 언박싱(Unboxing)

⭐ 박싱과 언박싱

● 박싱은 값 형식을 참조 형식으로 변환하는 것을 의미

    ○ 스택에 있는 값을 힙에 가져다 두는 것

    ○ 박싱은 암시적으로 발생

 

● 언박싱은 참조 형식을 값 형식으로 변환하는 것을 의미

    ○ 힙에 있는 걸 스택에 가져오는 것

    ○ 언박싱은 명시적으로 발생

 

 

Object 타입

 

C#의 모든 자료형의 토대가 되는 타입, 모든 것을 담을 수 있습니다.

    ○ 정말 모든 타입을 담기 때문에 타입 안정성이 좋지 않습니다.

    ○ 심지어 박싱, 언박싱 하는 과정에서 메모리 할당과 GC가 발생하기 때문에 성능적으로도 좋지 않습니다.

 

가능하면 제네릭을 사용하도록 하자.. ( 박싱, 언박싱은 대체제가 없는 경우에만 쓰자)

💡 object타입 vs var타입

object는 var와 같아보이지만 var는 우항의 식을 보고 맞는 타입을 추론하지만 object는 그냥 모든 자료형의 시초가 되는 타입입니다. 진짜 해당 값을 object 타입 변수에 넣어놓는다고만 생각하면 됩니다.

 


⭐ 박싱과 언박싱 과정

● 박싱의 과정

    1. 힙 영역에 새 객체를 생성

    2. 복사할 값 형식의 값을 생성한 힙 객체에 복사

    3. 스택 영역에서 오브젝트 변수가 해당 힙 객체의 주소를 저장

 

 

● 언박싱 과정

    1. 런타입 타입 검사, 오브젝트가 해당 타입을 박싱한 객체인지 검사 (타입이 다르면 예외 처리 발생)

    2. 타입이 같으면 힙 객체의 값을 스택의 변수에 복사

 

int a = 12;       //스택 영역에 a라는 공간에 12 저장
object o;         //스택 영역에 o라는 공간 생성
o = a;            //힙 영역에 a값인 12를 복사하여 생성 후 그 주소를 o에 저장
int b = (int)o;   //스택 영역에 b라는 공간을 생성 후 o가 가리키는 주소의 값(12)을 저장


● 위 코드의 박싱과 언박싱 과정을 그림을 통해 알아보겠습니다.


1.

 


2.

 

 

3.

 

 

4.

 

 

5.

 

 

 


⭐ 제네릭(generic)을 써야하는 이유

● 데이터의 타입을 일반화하여 코드의 재사용성을 높이는 기능입니다.

   제네릭을 사용하면 특정 데이터 타입에 의존하지 않는 유연한 클래스, 메서드, 인터페이스를 만들 수 있습니다.

 

● 제네릭과 오브젝트는 데이터 타입을 명시하지 않고도 데이터를 다룰 수 있지만 차이점이 있습니다.

 

    ○ 타입 안정성

        ■ 제네릭: 타입을 확인하여 타입 안정성을 보장

        ■ 오브젝트: 타입을 확인하지 않기 때문에 오류 발생 가능성 있음, 타입 안정성이 낮음

 

    ○ 성능

        ■ 제네릭: 박싱와 언박싱 과정이 없기 때문에 성능면에서 유리합니다.

        ■ 오브젝트: 박싱과 언박싱 과정에서 메모리 할당과 GC가 발생하기 때문에 성능면에서 좋지 않습니다.

 

    ○ 재사용성

        ■ 제네릭: 하나의 클래스/메서드 정의로 모든 타입에 대해 재사용이 가능합니다. 필요에 따라 조건을 걸 수도 있습니다.

        ■ 오브젝트: 타입 불일치 등의 검사가 필요, 코드 재사용이 제한적입니다.