본문 바로가기
언어(C, C++, C#)

[C#] object와 var

by 적용1 2024. 11. 4.
728x90

C#에서 object와 var 모두 명시적인 타입 지정 없이 변수 선언이 가능한데, 이 둘이 어떤 차이가 있는지 정리하려 한다.

object

- object는 .NET Framework에서 제공하는 어떤 데이터든 다룰 수 있는 데이터 형식이다.

 

object는 기본 데이터 형식(int, float 등) 뿐만 아니라 모든 복합 데이터 형식(구조체, 클래스, 배열 등), 사용자 정의 형식까지도 object 형식으로부터 상속받도록 개발되었다.

 

- object는 박싱(boxing)과 언박싱(unboxing)을 통해 값을 저장한다. 값을 박싱하여 heap에 저장하고, stack에 해당 값의 주소를 저장하고 있다가 필요할 때마다 참조하여 쓰는 방식이다.

출처 : https://while1.tistory.com/44

 

만약 참조하고 있는 값과 타입이 변경되어도, 기존의 참조를 제거하고 새로 박싱하여 heap에 저장하여 참조하므로 정상적으로 작동한다.

 

기존 heap에 저장된 object 객체는 이후에 GC에 의해 처리될 수 있도록 대기 상태가 된다.

출처 : https://while1.tistory.com/44

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 등 선언)과 동일한 방식이다.

출처 : https://while1.tistory.com/44

 

var은 위에서 설명했듯이 값을 보고 컴파일러가 타입을 추론하여 해당 타입에 맞는 크기만큼 메모리를 할당하여 삽입하게 된다. 아래 그림과 같이 var로 double형 변수를 선언하면 8byte의 공간이, int 형 변수를 선언하면 4byte의 공간이 할당되므로 다른 크기의 변수로 덮어씌우는 것은 불가능하다.

출처 : https://while1.tistory.com/44

 

var a = 5;
var b = 5.555;

a = b;

 

- var을 사용하게 되면 컴파일 시간은 약간 늘어날 수 있지만, 컴파일 후에는 명시적 타입과 동일하게 처리되므로 런타임 성능에 영향을 미치지 않는다.

요약

  • object는 값을 데이터 형의 최상위인 object형으로 변환하여 힙에 저장한 뒤(boxing) , 스택에는 해당 값에 대한 참조를 저장하여 unboxing을 통해 접근할 수 있다.
  • var은 암시적 데이터형으로, 선언하는 값에 따라 어떤 데이터형인지 판별하여 자동으로 메모리 영역을 할당받아 저장한다.
728x90

'언어(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