주녘공부일지

[C#] Object 형식과 박싱&언박싱 본문

Programming/Definition, Etc

[C#] Object 형식과 박싱&언박싱

주녘 2023. 10. 11. 18:06

1. Object 형식

모든 형식의 궁극적인 기반 클래스로 그 어떤 형식도 Object로 업캐스팅 할 수 있음 ( 참조 형식 )

 - C#의 모든 클래스 또는 구조체는 Object 클래스를 암시적으로 상속함

 ex) object 형식을 다루는 컬렉션 Stack

public class Stack
{
    int position;
    object[] data = new object[10];
    public void Push (object obj) { data[position++] = obj; }
    public object Pop() { return data[--position]; }
}

static void Main()
{
    Stack stack = new Stack();
    stack.Push("Sample");
    string s = (string)stack.Pop(); // 다운 캐스팅이므로 명시적 캐스팅 필요
}

object(.NET Framework : System.Object)의 모든 멤버

namespace System
{
    public class Object
    {
        public Object();
        ~Object();
        
        public static bool Equals(Object? objA, Object? objB);
        public static bool ReferenceEquals(Object? objA, Object? objB);
        public virtual bool Equals(Object? obj);
        
        public virtual int GetHashCode();
        public Type GetType();
        public virtual string? ToString();

        protected Object MemberwiseClone();
    }
}

C#의 형식 시스템

https://learn.microsoft.com/ko-kr/dotnet/csharp/fundamentals/types/

 

C# 형식 시스템

튜플, 레코드, 값 형식 및 참조 형식과 같은 C#의 형식 생성에 대해 알아봅니다.

learn.microsoft.com

2. 박싱&언박싱

값 형식과 참조 형식인 object 클래스 사이의 캐스팅을 가능하게 해주는 형식 통합의 수단으로, 참조 형식은 반드시 인터페이스나 Object 클래스여야 함

(참조 형식이 System.ValueType이거나 System.Enum인 경우도 가능)

 

1)박싱이란?

값 형식 데이터를 참조 형식 데이터로 형 변환하는 것

스택에 있는 데이터를 힙으로 복사하며 할당하고, 할당된 주소를 스택에 저장

단순 참조에 할당하는 것보다 20배까지 더 시간이 소모됨

+ 힙에 담기 위해 System.Object 형식으로 감싼다고 하여 박싱이라고 함

 

2) 언박싱이란?

참조 형식 데이터를 값 형식 데이터로 형 변환하는 것

힙에 있는 데이터를 복사하여 스택에 저장 // 명시적 캐스팅 필요

일반적으로 값을 할당하는 것보다 4배까지 더 시간이 소모됨

int x = 9;
object obj = x; // int 박싱
int y = (int)obj; // int 언박싱

언박싱이 이루어질 때에는 실제 객체 형식과 주어진 값이 일치하는지 점검하여 만일 부합하지 않으면 예외를 던짐

// 잘못된 예시
object obj = 9; // 9는 int 형식으로 추론
long x = (long)obj; // 예외 : InvalidCastException
// 적법한 예시
object obj = 9; // int 형식으로 추론
long x = (int)obj; // 자동 형 변환 int -> long

object obj2 = 3.5; // double 형식으로 추론
int y = (int)(double)obj2; // y = 3
// 언박싱 (double) -> 수치 형식 변환 (int)

배열은 참조 변환만 지원하고 박싱 변환은 지원하지 않음

object[] a1 = new string[3]; // 적법
object[] a2 = new int[3]; // 오류

- 박싱하고 언박싱을 할 경우 값 형식을 복사했던 힙 메모리는 GC의 수거 대상이 됨 ( 가비지 발생 )

- 이 때문에 object로 사용하는 ArrayList, Stack 등의 컬렉션들을 사용하지 않고 List<T>, Stack<T> 등의 제네릭 컬렉션을 사용하여 박싱&언박싱에 의한 오버헤드를 방지

 

https://learn.microsoft.com/ko-kr/dotnet/framework/performance/performance-tips

 

.NET 성능 팁 - .NET Framework

성능 팁을 확인하여 .NET에서 프로그램의 실행 속도를 향상시킵니다. boxing 및 unboxing, 문자열 및 종료자에 대한 팁을 참조하세요.

learn.microsoft.com

디스어셈블리로 확인하는 박싱과 언박싱 간단 예제

 

 

참고도서) C# 6.0 완벽가이드