const보다는 readonly 사용하기
const - 컴파일 타임 상수, 컴파일 타임에 변수가 값으로 대체된다.
readonly - 런타임 파일 상수, 런타임 타임에 값이 평가된다. 컴파일 타임에 값으로 대체되지 않고 상수에 대한 참조로 컴파일 된다.
//컴파일 타임 상수:
public const int Millennium = 2000;
//런타임 상수:
public static readonly int ThisYear = 2004;
const 예제)
if (myDateTime.Year == Millennium)
위 코드는 컴파일시 아래와 같이 컴파일 된다.
if (myDateTime.Year == 2000)
- const는 컴파일 시점에 값이 대체, readonly의 경우엔 const처럼 값으로 대체되지 않고 상수에 대한 참조로 컴파일된다.
-> 컴파일타임 상수가 빠르긴 하지만 런타임 상수에 비해 유연성이 떨어진다. 컴파일타임 상수는 성능이 매우 중요하고 상수의 값이 절대로 바뀌지 않는 경우에만 제한적으로 사용한다.
readonly의 유연성
- 생성자를 이용한 초기화 : readonly의 경우 생성자를 통해 초기화가 가능하다.
//컴파일되지 않음. readonly를 사용하면 초기화가 가능하다.
private const DateTime classCreation = new DateTime(2000, 1, 1, 0, 0, 0);
-> 클래스내에서 런타임 상수를 정의하는 경우라면 동일 클래스의 인스턴스라 하더라도 인스턴스별로 서로 다른 값을 갖게 구현할 수 있다. 그러나 컴파일타입상수(const)라면 컴파일 시 값이 결정됨으로 모든 인스턴스가 동일한 값을 가질 수밖에 없다.
프로그램 유지보수/호환성
Infrastrucutre 어셈블리 코드
public class UsefulValues
{
public static readonly int StartValue = 5;
public const int EndValue = 10;
}
Infastrucutre 사용 코드
for (int i = UsefulValues.StartValue; i < UsefulValues.EndValue; i++)
Console.WriteLine("value is {0}", i);
[출력]
Value is 5
Value is 6
...
Value is 9
* 위 코드의 Infrastrucutre 어셈블리만 수정.(프로그램 전체 rebulid하지 않음)
public class UsefulValues
{
public static readonly int StartValue = 105;
public const int EndValue = 120;
}
위의 수정으로 105~120까지의 값을 출력할 거라고 예상되지만, 결과는 아무것도 출력되지 않는다. 사용중인 프로그램에서 StartValue는 105, EndValue는 10을 계속 사용중이기 때문이다.
-> const는 컴파일 타임에 값을 대체해버리고, readonly는 런타임 상수이기 때문!
readonly를 사용하면 프로그램 전체를 리빌드하지 않고도 어셈블리의 변경사항을 올바르게 반영할 수 있다.
** 컴파일 타임 상수(const) 값을 수정할 때는 타입의 인터페이스 변경만큼 신중하게 해야 하며, 해당 상수를 참조하는 모든 코드를 재컴파일 해야한다. 런타임파일 상수의 경우 기존값만 변경하여도 기존 응용프로그램과의 코드 호환성이 유지된다.
const
- const는 성능이 빠르다. 상숫값으로 코드를 대체하면 readonly 변수를 통해 값을 참조하는 것보다 빠를 수밖에 없다. 성능과 유연성, 두가지를 비교해서 필요한 경우를 고려하여 구현한다.
- 컴파일 시 필요한 상숫값 : 특성(attribute)의 매개변수, switch/case문의 레이블, enum 상수와 같이 거의 수정이 필요없는 값은 const로 선언한다.
[참고]
EffectiveC# - 아이템2 : const보다는 readonly가 좋다.
'Software Development > C#' 카테고리의 다른 글
[Effective C#] string.Format()을 보간 문자열로 대체하라 (0) | 2021.01.17 |
---|---|
[Effective C#] 캐스트보다는 is, as가 좋다. (0) | 2021.01.16 |
[Effective C#] 지역변수 선언은 var를 사용/var 이해하기 (0) | 2021.01.09 |
C# yield 기초 이해하기 (0) | 2021.01.04 |
[Effective C#] C# 표준 Dispose 패턴 이해하기 (0) | 2021.01.02 |