공용 타입 시스템
C# 프로그래밍은 공용 타입 시스템(Common Type System, CTS)이 자리잡고 있다. 이는 .NET 환경에서 동작하는 모든 언어(C#, VB.NET, F# 등)가 동일한 데이터 타입을 공유하고 서로 소통할 수 있게 만드는 언어적 규약이다.
System.Object
.NET의 모든 타입은 예외 없이 System.Object를 최상위 부모로 둔다. 이는 객체지향 설계에서 중요하다.
-
통일성: 어떤 데이터든 object 타입으로 묶어서 처리할 수 있는 기반을 제공한다.
-
기본 기능의 보장: 모든 객체는 생성되자마자 ToString(), Equals(), GetHashCode(), GetType() 메소드와 같이 핵심 메소드를 상속받아 사용할 수 있다.
값 타입과 참조 타입
공용 타입 시스템의 가장 큰 분류는 데이터가 메모리에 저장되는 방식에 따른 구분이다. 이 차이를 이해하지 못하면 대규모 데이터 처리 시 성능 저하를 겪을 수 있다.
| 구분 | 값 타입(Value Type) | 참조 타입(Reference Type) |
|---|---|---|
| 상속 대상 | System.ValueType | System.Object 직접 상속 |
| 저장 위치 | 스택(Stack) 메모리 | 힙(Heap) 메모리 |
| 구성 요소 | struct, enum, 기본 데이터 타입 | class, interface, delegate, string |
| 복사 방식 | 깊은 복사(Deep Copy): 실제 데이터 값 복사 | 얕은 복사(Shallow Copy): 메모리 주소(참조)만 복사 |
| 메모리 해제 | 스코프를 벗어나면 즉시 스택에서 제거 | 가비지 컬렉터가 결정할 때까지 유지 |
메모리 모델
데이터가 메모리에 배치되는 구체적인 매커니즘은 다음과 같다.
-
스택(Stack): 메소드 실행 시 필요한 지역 변수들이 저장된다. CPU가 관리하여 속도가 압도적이지만 크기가 제한적이다. 깊은 재귀 호출 시 발생하는 StackOverflowException 예외는 여기서 유래한다.
-
힙(Heap): 관리형 힙(Managed Heap)이라고 불리며, 프로그램의 생명 주기 동안 살아있는 데이터 저장소이다. new 키워드로 생성된 클래스 인스턴스들이 여기에 위치한다.
성능의 함정
값 타입(Value)을 참조 타입(Object)으로 변환할 때 발생하는 현상이다. 심층 분석 시 성능 저하 요인이다.
-
박싱(Boxing): 스택에 있는 값 타입을 힙 메모리에 새롭게 복사하여 객체화하는 과정이다.
-
언박싱(Unboxing): 힙에 담긴 데이터를 다시 스택의 값 타입으로 가져오는 과정이다.
박싱이 일어날 때 새로운 객체가 힙에 생성되고 이는 가비지 컬렉터에 압박을 주게 되며, 수천 번의 루프 내에서 박싱이 발생하면 프로그램 전체의 프레임 워크가 저하될 수 있다.
타입 안정성
공용 타입 시스템은 모든 데이터의 타입을 엄격하게 관리하는 타입 안정성을 제공한다.
-
컴파일 타임 검사: 잘못된 타입 변환을 사전에 차단한다.
-
런타임 타입 정보(RTTI): GetType() 메소드를 통해 실행 중에서도 객체의 정확한 타입을 식별할 수 있게 하여, 안정적인 프로그램 운영을 보장한다.