C#에서 const 및 readonly 키워드는 선언된 후에는 수정할 수 없는 변경할 수 없는 값을 정의하는 데 사용됩니다. 그러나 둘 사이에는 몇 가지 중요한 차이점이 있습니다.
상수
const 수정자는 컴파일 타임에 알려지고 변경되지 않는 상수 값을 선언합니다. 즉, 변경할 수 없습니다. C#에서는 기본 제공 형식만 const로 표시할 수 있습니다. 클래스, 구조체 등과 같은 사용자 정의 유형은 const일 수 없습니다. 또한 메서드, 속성 또는 이벤트와 같은 클래스 멤버 유형은 상수로 표시할 수 없습니다.
선언하는 동안 상수를 초기화해야 합니다.
class Period{ public const int hours = 12; public const int minutes = 60; }
상수는 모든 가시성 수정자로 표시될 수 있습니다(예:private, public, protected, protected internal 또는 private protected).
상수는 정적 값으로도 작동합니다. 즉, 상수 값은 클래스의 모든 인스턴스에 대해 동일합니다. static 키워드로 명시적으로 표시할 필요는 없습니다. 해당 클래스의 인스턴스 변수를 사용하여 상수에 액세스할 수 없지만 클래스 이름을 사용해야 합니다.
읽기 전용
읽기 전용으로 표시된 필드는 선언 중에 또는 생성자에서만 할당할 수 있습니다. 클래스의 인스턴스가 생성되면 읽기 전용 필드를 수정할 수 없습니다.
필드가 값 유형인 경우 읽기 전용으로 표시하면 변경할 수 없습니다. 반면에 읽기 전용 필드가 참조 유형이면 변수가 참조하는 개체의 데이터를 계속 변경할 수 있습니다. 그러나 새 개체를 가리키도록 해당 참조를 변경할 수는 없습니다.
class Person{ private readonly string _title; private readonly string _skill; public Person(string title, string skill){ _title = title; _skill = skill; } }
읽기 전용 필드는 필드 선언과 모든 생성자에서 여러 번 할당할 수 있습니다. 또한 사용하는 생성자에 따라 다른 값을 가질 수 있습니다.
둘 사이의 중요한 차이점은 한 어셈블리에서 선언된 const 또는 readonly 필드가 다른 어셈블리에서 사용될 때 컴파일되는 경우입니다.
-
const 값의 경우 찾기-바꾸기와 같습니다. 상수 값은 두 번째 어셈블리의 중간 언어로 '구워집니다'. 즉, 상수를 업데이트하면 두 번째 어셈블리는 다시 컴파일할 때까지 여전히 첫 번째 값을 갖게 됩니다.
-
읽기 전용 값의 경우 메모리 위치에 대한 참조와 같습니다. 값은 두 번째 어셈블리의 중간 언어로 구워지지 않습니다. 즉, 메모리 위치가 업데이트되면 두 번째 어셈블리가 다시 컴파일하지 않고 새 값을 가져옵니다. 읽기 전용 필드를 업데이트하면 사용자 어셈블리를 컴파일할 필요 없이 첫 번째 어셈블리만 컴파일하면 됩니다.
예시
using System; class Program{ static void Main(){ Console.WriteLine(Period.HOURS); var person = new Person("John", "Programmer"); person.Print(); } } class Period{ public const int HOURS = 12; public const int MINUTES = 60; } class Person{ private readonly string _title; private readonly string _skill; public Person(string title, string skill){ _title = title; _skill = skill; } public void Change(string skill){ // Error: A readonly field cannot be assigned to // this._skill = skill; } public void Print(){ Console.WriteLine($"{_title}: {_skill}"); } }
출력
12 John: Programmer