.Net framework는 모든 타입의 최상위 타입을 System.Object로 정의하며 이 Object는 모든 타입의 베이스클래스이다. 타입에는 값타입, 참조타입, 포인터 타입등으로 나뉘어진다.
값 타입
주로 값을 저장할 때 쓰는 저장소, 다형적이지 못하다. 값 타입은 스택영역에 저장된다. (int, char, double ...)
값타입은 Object를 상속받은 System.ValueType을 상속받은 구조체이다.(System.ValueType)
int -> System.Int32로 정의. 상속관계는 Object->ValueType->Int32 (Int32 구조체)
char -> System.Char로 정의. 상속관계는 Object->ValueType->Char(Char 구조체)
참조타입
모든 타입의 base class인 System.Object를 상속받으며, 힙 영역에 저장된다. 값형식은 해당 데이터에 직접 값이 저장된다면, 참조 타입은 데이터(개체)에 대한 참조가 저장된다.
참조타입은 처음 변수를 선언하면 값타입과 달리 메모리가 생성되지 않는다.
Class A
{
}
A a = null; // 메모리 생성되지 않음.
이후 A를 생성한다면 실제 생성된 A는 힙에 메모리를 할당, a는 그 값에 대한 참조만 스택에 저장한다.
A a = new A(); // 메모리 생성, 변수 a는 생성된 A의 참조(주소)만 갖게 됨.
a를 새로운 aa에 할당한다면 새로운 메모리를 할당하지 않고 참조하는 값만 복사.
A aa = a; // 새로운 메모리를 할당하지 않고, a의 참조값을 갖는 값만 복사함.
-> 참고 : C# 참조형식
Boxing(박싱)
- 값 타입의 객체를 참조 타입(Object)로 변환
int i = 123;
object o = i; //박싱
Console.WriteLine(o.ToString());
-> 단순한 형변환같지만 값타입은 스택에 저장되어 있고 참조타입은 힙에 저장되어 있다. 그래서 위 과정을 수행하기 위해선 스택에 저장된 값타입을 힙타입으로 복사가 한번 일어난다. 그리고 힙에 복사된 이 영역을 참조타입이 가리키게 되는 일을 수행한다.
Unboxing(언박싱)
- 참조타입을 값타입으로 변환
int i = 123; // a value type
object o = i; // boxing
int j = (int)o; // unboxing
-> 박싱과 반대로, 힙에 있던 데이터를 다시 스택으로 복사가 일어난다.
* 박싱과 언박싱은 변환 과정에서 스택<->힙 과정에 복사가 일어날 뿐만 아니라, 복사 후 불필요한 가비지도 남아 성능상에 문제가 발생할 수도 있다. 가능한 박싱과 언박싱을 최소화하여 구현하는게 좋다. (MSDN 성능 팁)
[참고]
Effective C# -아이템9:박싱과 언박싱을 최소화하라
MSDN - boxing 및 unboxing (C# 프로그래밍 가이드) : 링크
'Software Development > C#' 카테고리의 다른 글
.Net Framework Guideline - Naming Rule(.net 프레임워크 디자인 지침 - 명명 지침) 정리 (0) | 2021.08.25 |
---|---|
C# 기초 - 이벤트와 델리게이트 (Event & Delegate) (1) | 2021.08.24 |
[Effective C#] new 한정자 사용 (0) | 2021.01.29 |
[C#] abstract & virtual 연산자와 override & new 연산자 (0) | 2021.01.25 |
[Effective C#] nameof() 연산자 (0) | 2021.01.24 |