* 정의

 

C#에서는 값을 메모리에 저장하는 방법에 따라 데이터 타입을 크게 2가지로 분류한다.

 

  • 1. 값 타입(Value type)
  • 2. 참조 타입(Reference type)

 

* 값 타입(Value type)

 

- 정의

 

값 타입은 데이터의 값을 직접 메모리 공간에 보유하고 있는 경우를 의미한다.

값 타입 변수는 스택에 할당된 메모리에 데이터의 값을 직접 포함하는 변수를 의미한다.

 

 

- 특징

 

@ 스택에 데이터의 값을 저장하는 것은 효율적이지만, 값 타입의 제한된 생명주기는 다른 클래스와 데이터를 공유하기에 비효율적이다.

 

@ 각 값 타입 변수는 데이터의 고유한 복사본을 가지고 있기 때문에 (ref, out 키워드를 사용하지 않는다면)메소드를 통해서 이 변수를 변경할 수 없다. 값 타입 변수를 메소드를 통해 넘겨주게 되면 시스템은 이 변수를 복사하여 새롭게 변수를 만들게 된다. 

 

@ 스코프를 빠져나가면 값이 스택에서 삭제된다.

 

@ C#의 값 타입은 다음 타입으로 분리된다.

  • 단순 타입
  • 열거형 타입
  • 구조체 타입
  • nullable 값 타입

 

@ 값 타입은 System.ValueType을 상속받는다.

 

@ 인터페이스를 제외하고 상속받을 수 없다. // IL에서 확인해보면 Sealed Class로 정의된다.

 

 

ildasm 툴로 확인한 값 타입

 

 

* 참조 타입(Reference type)

 

- 정의

 

값 타입가 다르게 데이터의 값을 직접 메모리에 저장하지 않는다. 대신 데이터의 값이 저장된 메모리를 저장한다. 간단히 참조 타입은 데이터의 값이 들어있는 다른 메모리 공간에 대한 포인터라고 생각하면 된다.

 

 

- 특징

 

@ 참조 타입은 데이터 값을 힙에 저장되고 해당 데이터 값이 존재하는 힙 메모리 주소를 스택에 저장한다.

 

@ 참조 타입을 선언하는 것은 오버헤드가 더 크지만 다른 클래스에서 접근할 수 있다는 장점이 있다.

 

@ 참조 타입을 사용하면 서로 다른 변수가 같은 객체를 참조하도록 할 수 있다. 참조 타입 변수를 메소드를 통해 넘겨주게 되면 이 데이터 값에 대한 새로운 복사본을 만들지 않는다. 대신 주소만 넘겨주게 된다. 만약 메소드에서 변수가 변경되면 원본 참조 타입에 영향을 준다.

 

@ 참조 타입 변수의 스코프를 벗어나게 되면 메모리는 바로 힙에 반환되지 않고 가비지 컬렉터가 해당 데이터가 더 이상 쓰이지 않을 때 수거하게 된다.

 

@ C#의 참조 타입은 다음 타입으로 분리된다.

  • 클래스 타입
  • 인터페이스 타입
  • 배열 타입(요소가 값 타입인 경우 포함)
  • 델리게이트 타입
  • nullable 참조 타입 // C# 8.0부터 명시적으로 nullable을 표현하도록 하고 있다.

@ 참조 타입은 System.Object를 상속받는다.

 

@ 90%이상은 ref, out 키워드를 사용하나 안하나 똑같이 동작한다. (string과 같은 불변 참조 타입 제외)

 

 

ildasm 툴로 확인한 참조 타입

 

 

* 값 타입(Value type) vs 참조 타입(Reference type)

 

  값 타입(Value type) 참조 타입(Reference type)
Base 클래스 System.Object System.ValueType
정의 방법 struct로 정의 class로 정의
메소드에 참조로 넘겨주는 방법 ref, out 키워드 사용 일반적으로 참조로 넘김
불변 참조 타입의 경우 ref, out 키워드를 사용
데이터 값의 저장 위치 스택
할당 시 오버헤드 작다 크다
생명 주기 스코프를 빠져나가면 바로 삭제 스코프를 빠져나가면 가비지 컬렉터의 판단 하에 적절한 시점에 삭제
타입 종류
  • 단순 타입
  • 열거형 타입
  • 구조체 타입
  • nullable 값 타입
  • 클래스 타입
  • 인터페이스 타입
  • 배열 타입(요소가 값 타입인 경우 포함)
  • 델리게이트 타입
  • nullable 참조 타입 // C# 8.0부터 명시적으로 nullable을 표현하도록 하고 있다.
상속 가능 여부 sealed class로 정의되기 때문에 인터페이스만 상속 가능하다. 사용자가 sealed 로 정의하지 않았으면 어느 클래스든 상속 가능하다.

 

'C#' 카테고리의 다른 글

[C#] string vs StringBuilder  (0) 2022.06.28
[C#] Nullable 타입  (0) 2022.06.28
[C#] .NET  (0) 2022.06.28
[C#] abstract, sealed  (0) 2022.04.08
[C#] 정적 클래스(static class)  (0) 2022.04.08

+ Recent posts