const보다는 readonly가 좋다.



[ Content ]

- const
    . 컴파일 타임 상수.
    . 컴파일 타임에 변수가 값으로 대체되어, 메서드 내부에서도 선언이 가능.
    . 컴파일 타임에 상수를 리터럴로 대체해야 하기 때문에, 내장된 숫자형, enum, 문자열, null과 같은 내장 자료형만 사용 가능.

- readonly
    . 런 타임 상수.
    . 컴파일 타임에 값으로 대체되는 것이 아닌, 상수에 대한 '참조'로 컴파일되어 메서드 내에서는 선언 불가능.
    . 꼭 생성과 동시에 초기화하지 않아도 되며, 생성자에서 최초 1번 초기화 가능. 그 이후에는 수정 불가능.
    . 어떤 타입과도 사용될 수 있다.


 위 내용의 런타임 상수와 컴파일 상수의 차이 중, 중요한 차이는 값이 런타임에 평가된다는 점입니다. 
런타임 상수를 참조하는 코드를 컴파일하면 컴파일 타임 상수처럼 코드를 값으로 대체하지 않고, 참조 코드를 생성합니다.
이러한 차이가 유지 및 보수에 상당한 영향을 미칩니다.


1
2
3
4
5
public class UsefulValues
{
    public static readonly int StartValue = 5;
    public const int EndValue = 10;
}



 위와 같이 정의하여 값을 사용하다 아래와 같이 수정할 때,


1
2
3
4
5
public class UsefulValues
{
    public static readonly int StartValue = 105;
    public const int EndValue = 110;
}



 수정 후, 리빌드하지 않고 사용한다면, StartValue에 대한 값은 참조 코드로 인해 런타임에 105로 읽어드리지만, EndValue는 이전 컴파일 시점에 대체되었던 10으로 값이 유지됩니다.

 이처럼 컴파일 타임 상수의 값을 수정할 때는 신중해야 하며, 모든 코드를 재컴파일해야 합니다. 하지만, 런타임 상수는 값 변경만으로도 수정이 가능하며 이진 호환성도 그대로 유지됩니다.


 이와 반대로 재컴파일 전까지 기존 값을 유지하고 싶은 경우도 있을겁니다. 이러한 경우 컴파일 타임 상수를 활용하면 됩니다.
또한, 선택적 매개 변수에 대한 기본값, 특성의 매개 변수, switch/case문의 레이블, enum 정의에 사용되는 상수 등도 컴파일 시에 사용되어야 하므로 const를 통해 초기화 해야합니다.
        - 선택적 매개 변수 : https://loveme-do.tistory.com/2

 const가 가지는 장점은 성능이 빠르다는 것인데, 이를 통해 얻을 수 있는 성능 개선 효과가 크지 않아, 위와 같은 예외적인 상황을 제외한다면 readonly를 사용하는 것이 좋습니다.




[ Digression ]


 아직 많지 않은 경험으로 사용하면서 가장 크게 느낀 장점은 readonly가 모든 타입과 사용할 수 있다는 점입니다.
상수 사용에 내장 타입과도 많이 사용하지만 직접 정의한 타입을 사용하는 경우도 많아 자주 사용할 수 밖에 없습니다. 
 위의 내용처럼 유지 및 보수 시에 확실히 상수 값 변경에 부담을 가지지 않아도 된다는 점은 크게 느낄 수 있는 장점이라 생각합니다.






참 고 : Effective C# 

지역 변수를 선언할 때는 var를 사용하는 것이 낫다.



[ Content ]
- var : 익명 타입을 제공하는 C#에서 타입을 암시적으로 선언하는 키워드.


- 이유 
    1. 적절한 사용으로 코드의 가독성을 높일 수 있다.


 예를 들어, Dictionary<int, Queue<String>>과 같은 기술 타입 자체보다 타입을 유추할 수 있는 변수 이름과 암시적 타입 선언을 사용하는 것이 가독성을 올릴 수 있습니다.

 당연하지만, 무분별한 사용은 오히려 가독성을 해칠 수 있죠!! 
특히, 내장 숫자 타입들과 var를 함께 사용할 때는 주의해야 합니다. 내장 숫자 타입들은 다양한 형변화 기능을 가지고 있고, 정밀도도 각기 다르기 때문에 숫자 타입과 var를 함께 사용하면 가독성과 정밀도에 관련되어 혼돈을 유발할 가능성이 있기 때문입니다. 또한 변수 타입이 쉽사리 짐작되지 않는 경우라면, 암시적 선언보다는 명시적을 선언하는 편이 낫습니다.


2. 쿼리문 사용 시, 반환 타입이 IEnumerable<T>와 IQueryable<T> 중, 정확한 타입을 알지 못한 채, 명시적으로 타입을 지정하게 된다면, 득보다 실이 많을 수 있다. 


 IQueryable<T>를 IEnumerable<T>로 받게되면 강제 형변환이 발생하고, IQueryProvider가 제공하는 장점을 읽게 됩니다. 이 때, IQueryable<T>는 IEnumeable<T>를 상속받은 것으로 형변환이 일어날 뿐, 에러가 발생하지 않아 파악하는데 어려움이 생깁니다.

 . IEnumerable<T>와 IQueryable<T> 차이
   http://monkeychoi.blog.me/220556573557



[ Digression ]


 실제로 코드를 작성하면서 var타입을 많이 사용하고 있습니다. 프로젝트 상의 상속구조와 객체들이 많아지면 함수의 이름이나 변수의 이름으로 필요한 것을 찾아 쓰고 이에 따른 반환 값이나 지역 변수를 사용할 때 var타입을 사용하는 편입니다. 생각보다 복잡하게 선언된 타입들도 많아 코드량도 줄일 수 있고 가독성을 높일 수 있다고 생각합니다.

 초반 작업에는 내장 숫자 타입을 var로 받아 의도치 않은 정밀도를 봤던 경우도 있었습니다. 위의 내용처럼 무분별한 사용이 아닌 적절히 사용한다면 확실히 편하게 사용할 수 있는 부분들이 많습니다.






참 고 : Effective C# 

+ Recent posts