C#에는 값을 상수화하는 방법으로 2개의 키워드를 제공해준다.

바로 const와 readonly이다.

(상수화 : 변수에 저장되어 있는 값을 바꿀 수 없도록 하는 것)

 

그렇다면, 두 키워드에는 무슨 차이가 있을까?

가장 큰 차이는 const로 선언된 변수는 컴파일 타임에 값이 결정되고, readonly는 런타임에 결정된다는 것이다.

 

const 변수는 컴파일 타임에 값이 정해져야 하기 때문에 선언을 할 때 반드시 값을 초기화해야 한다.

//1
const int A;
A = 3;

//2
const int A = 3;

A라는 변수에 3이라는 값을 할당하는 방법은 위처럼 2가지가 있지만, const 변수에게 있어 1번 방식은 허용되지 않는다.

왜냐하면 컴파일 타임에 값을 정할 수 없기 때문이다.

 

이러한 이유로 const가 붙은 필드(멤버 변수)를 보유한 클래스의 경우, 모든 인스턴스가 같은 값을 공유하게 된다.

그렇다면 생각해보자. 모든 인스턴스가 같은 값을 공유할 것이 확실하다면, 굳이 인스턴스별로 메모리를 계속 할당할 필요가 있을까? 당연히 그럴 필요가 없다.

 

그래서 const 변수는 static이랑 동일하게 작동하게 된다. 클래스 단위로 1개만 생성되며, 데이터 영역에 위치하게 된다.

 

const가 컴파일 타임에 값을 결정해야 한다는 이유로 발생하는 특징이 하나 더 있다.

바로 커스텀 클래스에는 const를 사용할 수 없다는 것이다. 

왜냐하면, 클래스의 경우 생성자가 호출되어야만 그 값이 확정되기 때문에 컴파일 타임에는 정확한 값을 결정할 수가 없기 때문이다.

 

이번엔 readonly에 대해 알아보자.

 

readonly는 const와 다르게 생성자에서 한 번 초기화하는 것이 가능하다. 생성자가 아닌 곳에서는 불가능하다.

이러한 특성 때문에, 생성자 파라미터를 활용하면 인스턴스 별로 다른 값을 가지게 하는 것이 가능하다.

 

하지만, 생성자에서만 초기화 된다는 이유 때문에 한 가지 문제가 생긴다.

예를 들어, 아래 코드를 보자.

public void Function()
{
    readonly int A;
    A = 3;
}

우리는 상수화된 값을 지역 내에서 선언하고 사용하고 싶을 수도 있다.

그런데 readonly는 생성자에서만 값을 초기화하는 것이 가능하다고 했다.

 

그럼 위의 코드는 작동할까? 당연히 작동하지 않는다.

readonly는 이러한 이유로 지역변수로 사용할 수 없고 필드(멤버 변수)로만 사용이 가능하다.

 

readonly는 위에서 언급했던 것처럼 생성자에서 초기화되기 때문에 각 인스턴스가 다른 값을 가질 수도 있다.

이런 이유로 const처럼 static으로 선언되지 않고 일반 변수처럼 선언된다.

인스턴스가 100개라면 100개의 변수가 생성되는 것이다.

 

그렇기 때문에 const보단 더 유연하게 사용할 수 있겠지만, 메모리 사용량은 더 크다는 단점이 생긴다.

또한, readonly의 경우 힙영역에 생성되기 때문에 const변수보다 읽기 연산이 더 느릴 수 있다. 

 

하지만, readonly의 경우 const와 다르게 커스텀 클래스에도 사용이 가능하기 때문에 const보다는 더욱 광범위하게 사용이 가능하다.

 

두 키워드의 차이를 표로 한 눈에 알아보자.

const readonly
컴파일 타임에 값이 결정되어야 한다. 런타임에 값이 결정되어도 된다.
선언과 초기화가 함께 이루어져야 한다. 선언과 초기화를 분리할 수 있다. (초기화는 생성자에서 가능)
커스텀 클래스에는 사용이 불가능하다. 모든 자료형에 대해 사용이 가능하다.
static변수와 같이 프로세스 전체에 1개만 생성된다. 인스턴스의 개수만큼 변수가 생성된다.
데이터 영역에 위치한다. 힙 영역에 위치한다.
필드와 지역 변수에 모두 사용할 수 있다. 필드에만 사용이 가능하다.

 

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

C# - LINQ (Language Integrated Query)  (0) 2024.09.02
C# - ref, out  (0) 2024.08.13
C# - is, as 연산자  (0) 2024.08.07
C# - 클래스, 접근 제한 지정자, 프로퍼티  (0) 2024.07.27
C# - C#의 자료형  (0) 2024.07.24

+ Recent posts