const 한정자는 값이 컴파일 시점에 알려져 있고 프로그램의 수명 동안 바뀌지 않는 모든 필드에 적용할 수 있으며, 일반적으로 적용하는 게 좋아요.
private const int num = 1729;
public const string title = "Grand" + " Master";
readonly 한정자는 const로 만들 수는 없지만 값이 프로그램의 수명 동안 바뀌지 않고, 인라인 이니셜라이저로 설정되거나 인스턴스화 과정에서(생성자 또는 생성자가 호출한 메서드에 의해) 설정되는 모든 필드에 적용할 수 있으며, 일반적으로 적용하는 게 좋아요.
private readonly int num;
private readonly System.Random rand = new System.Random();
public MyClass(int num)
{
this.num = num;
}
보안에 민감한 상황이라면(또는 개발자마다 우선순위와 목표가 다른 큰 코드베이스에서라면 더욱) 메서드의 변경 가능한 매개변수를 그대로 받아 저장하거나, 클래스의 변경 가능한 멤버를 반환 값이나 out 매개변수로 노출해서 클래스의 공개 API가 우회되도록 두어서는 안 돼요.
readonly 한정자는 필드의 값이나 참조를 덮어쓰지 못하게 막아 주지만, 참조 형식의 멤버는 전혀 보호해 주지 않아요.
readonly List<int> ints = new List<int>();
void Foo()
{
ints.Add(1); // ok
ints = new List<int>(); // fails to compile
}
참조 형식의 모든 멤버를 보호하려면 필드를 readonly로 만들고, set 접근자 없이 자동 구현 속성을 정의하면 돼요.
기본 클래스 라이브러리(Base Class Library, BCL)는 컬렉션의 멤버가 갱신되지 않도록 해야 할 때 쓸 수 있는 읽기 전용 버전의 컬렉션 몇 가지를 제공해요. 이들은 래퍼 형태로 제공돼요.
ReadOnlyDictionary<T>는 Dictionary<T>를 읽기 전용으로 노출해요.ReadOnlyCollection<T>는 List<T>를 읽기 전용으로 노출해요.지난번 developer-privileges에서 만난 인증 시스템을 좀 손봐야 해요. 코드를 정리하는 일을 맡게 되었어요. 이런 정리 작업은 앞으로 이 코드를 유지보수할 사람들을 편하게 해 줄 뿐만 아니라, 몇 가지 보안 취약점을 드러내고 고쳐 줄 거예요.
const로 설정해요리팩터링 작업이에요. Authenticator나 Identity의 멤버 중 적절하다고 생각하는 곳에 const 한정자를 추가해요.
readonly로 설정해요리팩터링 작업이에요. Authenticator 클래스나 Identity 구조체의 필드 중 적절하다고 생각하는 곳에 readonly 한정자를 추가해요.
Authenticator 클래스나 Identity 구조체의 속성 중 적절한 곳에서 set 접근자를 제거하거나 private로 만들어요.
현재 관리자 신원 필드는 Admin을 호출하면 반환돼요. 호출한 쪽에서 이 필드를 수정할 수 있어서 그다지 좋지 않아요. 호출자가 Authenticator 객체의 관리자 정보를 수정하지 못하도록 막을 방법을 찾아보세요.
현재 하드 코딩된 권한 있는 개발자 신원을 담은 딕셔너리는 GetDevelopers()를 호출하면 반환돼요. 호출한 쪽에서 이 딕셔너리를 수정할 수 있어서 그다지 좋지 않아요. 호출자가 Authenticator 객체의 개발자 정보를 수정하지 못하도록 막을 방법을 찾아보세요.
Exercism에 가입하고 C# 트랙을 개념 62개연습 문제 178개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.