C#에서 object와 var 모두 명시적인 타입 지정 없이 변수 선언이 가능한데, 이 둘이 어떤 차이가 있는지 정리하려 한다.
object
- object는 .NET Framework에서 제공하는 어떤 데이터든 다룰 수 있는 데이터 형식이다.
object는 기본 데이터 형식(int, float 등) 뿐만 아니라 모든 복합 데이터 형식(구조체, 클래스, 배열 등), 사용자 정의 형식까지도 object 형식으로부터 상속받도록 개발되었다.
- object는 박싱(boxing)과 언박싱(unboxing)을 통해 값을 저장한다. 값을 박싱하여 heap에 저장하고, stack에 해당 값의 주소를 저장하고 있다가 필요할 때마다 참조하여 쓰는 방식이다.
만약 참조하고 있는 값과 타입이 변경되어도, 기존의 참조를 제거하고 새로 박싱하여 heap에 저장하여 참조하므로 정상적으로 작동한다.
기존 heap에 저장된 object 객체는 이후에 GC에 의해 처리될 수 있도록 대기 상태가 된다.
int a = 30;
object b = (object)a;
WriteLine("a : " + a);
WriteLine("b : " + b);
// 새로운 타입의 새로운 값을 넣음
b = "안녕";
WriteLine("b : " + b);
- object가 boxing되어 heap에 저장되는 정보
- object 헤더 : 객체에 대한 메타데이터로, GC에서 객체를 추적하기 위한 정보들이 포함되어 있다.
- 타입 정보 : CLR이 박싱된 데이터의 타입을 알 수 있어야하기에 해당 데이터 타입을 알려주는 포인터나 참조 정보가 필요하다.
- 박싱된 값 : 실제 값이 저장되는데, 이 때 차지하는 크기는 실제 값의 데이터 크기와 같다.(int = 4byte, double = 8byte)
- object가 밖에서 선언했을 때보다 차지하는 메모리 크기가 큰데 사용하는 이유
- 컬렉션 및 메서드의 유연성 : 타입에 구애받지 않고 다양한 값 타입을 받을 수 있도록 한다.
- 다형성 : object 타입은 모든 타입의 상위 타입이므로 박싱을 통해 다형성을 활용할 수 있다. 예를 들어, 메서드가 object 타입의 파라미터를 받는다면, 모든 타입을 한 메서드에서 처리할 수 있다. 이 경우 메서드의 재사용성이 높아지고, 다양한 타입을 허용하는 다형성을 구현할 수 있다.
- 박싱과 언박싱
- 박싱(Boxing) : 값 타입의 데이터(int, float, struct)를 참조 타입(object, dynamic)으로 변환하는 과정
- 언박싱(Unboxing) : 참조 타입으로 박싱된 데이터를 원래의 값 타입으로 변환하는 과정
var
- var은 컴파일러가 변수를 생성할 때, 값을 보고 타입을 추론하여 stack에 영역을 지정(타입에 맞는 크기만큼)하고 값을 삽입한다. 즉, 타입을 추론하는 부분만 제외하면 명시적 선언(int, float 등 선언)과 동일한 방식이다.
var은 위에서 설명했듯이 값을 보고 컴파일러가 타입을 추론하여 해당 타입에 맞는 크기만큼 메모리를 할당하여 삽입하게 된다. 아래 그림과 같이 var로 double형 변수를 선언하면 8byte의 공간이, int 형 변수를 선언하면 4byte의 공간이 할당되므로 다른 크기의 변수로 덮어씌우는 것은 불가능하다.
var a = 5;
var b = 5.555;
a = b;
- var을 사용하게 되면 컴파일 시간은 약간 늘어날 수 있지만, 컴파일 후에는 명시적 타입과 동일하게 처리되므로 런타임 성능에 영향을 미치지 않는다.
요약
- object는 값을 데이터 형의 최상위인 object형으로 변환하여 힙에 저장한 뒤(boxing) , 스택에는 해당 값에 대한 참조를 저장하여 unboxing을 통해 접근할 수 있다.
- var은 암시적 데이터형으로, 선언하는 값에 따라 어떤 데이터형인지 판별하여 자동으로 메모리 영역을 할당받아 저장한다.
'언어(C, C++, C#)' 카테고리의 다른 글
[C#] Virtual, Abstract, Interface (0) | 2024.11.05 |
---|---|
[C#] this (2) | 2024.11.05 |
[C#] C#의 Collection (0) | 2024.11.04 |
[C++] C++의 STL (0) | 2024.11.03 |
C# vs C++ (2) | 2024.11.02 |