C# - Object 타입과 박싱 언박싱

Justin·2022년 11월 4일
0

C#

목록 보기
7/7
post-thumbnail

개요

Object 타입을 사용해본적은 없고, Debug.Log() 같은 곳에서 Object 타입으로 받는 것만 봤었다.

박싱과 언박싱을 공부하던 도중 Object 형식으로 감싸고, 풀어주는데 왜 Object 타입이 다른 타입들을 다 담을 수 있는지 등에 대한 의문이 생겨 공부해보기로 했다.

Object 타입이란

Object 타입은 값 형식(float, int ...) 부터 참조(Class, string..) 그리고 우리가 만들어내는 모든 데이터 타입들까지도 객체를 담을 수 있다.

어떻게 가능할까?

C#에서는 모든 데이터 형식이 Object를 '상속' 받도록 구조가 짜여져있기 때문이다.

Object는 모든 타입의 부모이기에 모두를 담을 수 있었고 이를 통해서 object 배열 같은 것을 선언하면 다양하게 타입을 담아두며 편리하게 사용할 수 있다.

하지만! 이렇게 편리하다고 마구잡이로 사용하게 되면 메모리 낭비가 발생하기에 박싱과 언박싱의 개념을 이해해야한다.


박싱과 언박싱

스텍에 저장되어있는 값 타입의 데이터를 -> Object 타입을 통해 힙 영역에 저장하는 과정을 박싱(Boxing) 이라고 한다.

말 그대로 박스로 감싸는 과정인데 Object에 값 타입의 int 값을 넣으면 이렇게 스텍에 담겨야하는 값이 박스로 감싸져 힙 메모리에 저장된다.

 object obj = 20;

이렇게 박스로 감싸진 데이터를 풀어내는 과정을 언박싱(Unboxing) 이라 한다.

물론 이렇게 바로 값을 넣는다고 언박싱이 가능한 건 아니고, 명시를 해주어야한다.

int a = obj; // 에러

주의
박싱은 단순히 힙에 넣는 과정에 비해 약 20배의 시간이 소모되며 언박싱 시에는 4배의 시간이 소모된다고 한다. 그렇기에 박싱이 사용되는 부분을 자제해야한다.

예시로 지난 번 작성한 글을 보면 Object 타입으로 값을 받아 박싱이 발생하는걸 막기 위해 IEqualityCompaerer를 float 타입으로 명확하게 선언해주어서 float 값만 들어가도록 제한 해주는 작업을 했었다.

더 가벼운 예시로는 Debug.Log() 가 있다 이 또한 박싱 과정이 발생하여 최적화에 문제가 되기 때문에 에디터에서만 사용하고, 빌드 시에는 제거하거나 아래와 같이 어트리뷰트를 사용하여 에디터 루프 내에서만 사용되게 제한을 해준다.

public static class Debug
{
    [Conditional("UNITY_EDITOR")]
    public static void Log(object message)
        => UnityEngine.Debug.Log(message);
}
profile
인디 게임을 만들며 공부하고 있습니다.

0개의 댓글