readonly(C# 참조)

readonly 키워드는 다섯 가지 상황에서 사용할 수 있는 한정자입니다.

  • 필드 선언에서 필드에 대한 할당을 나타내는 readonly는 선언의 일부로 또는 동일한 클래스의 생성자에서만 발생할 수 있습니다. 필드 선언과 생성자 내에서 읽기 전용 필드를 여러 번 할당 및 재할당할 수 있습니다.

    생성자가 종료된 후에는 readonly 필드를 할당할 수 없습니다. 이 규칙의 의미는 값 형식과 참조 형식에서 서로 다릅니다.

    • 값 형식에는 해당 데이터가 직접 포함되므로, readonly 값 형식인 필드는 변경할 수 없습니다.
    • 참조 형식에는 해당 데이터에 대한 참조가 포함되므로, readonly 참조 형식인 필드는 항상 같은 개체를 참조해야 합니다. 해당 개체는 변경 불가능하지 않을 수 있습니다. readonly 한정자는 필드 값을 참조 형식의 다른 인스턴스로 바꾸는 것을 방지합니다. 그러나 이 한정자는 필드의 인스턴스 데이터가 읽기 전용 필드를 통해 수정되는 것을 방지하지는 않습니다.

    Warning

    변경 가능한 참조 형식인, 외부에서 볼 수 있는 읽기 전용 필드가 포함된 외부에서 볼 수 있는 형식은 보안상 취약할 수 있으며, 경고 CA2104: "읽기 전용 변경 가능한 참조 형식을 선언하지 마세요."를 트리거할 수 있습니다.

  • readonly struct 형식 정의에서 readonly는 구조체 형식을 변경할 수 없음을 나타냅니다. 자세한 내용은 구조체 형식 문서의 readonly 구조체 섹션을 참조하세요.

  • 구조체 형식 내 인스턴스 멤버 선언에서 readonly는 인스턴스 멤버가 구조체의 상태를 수정하지 않음을 나타냅니다. 자세한 내용은 구조체 형식 문서의 readonly 인스턴스 멤버 섹션을 참조하세요.

  • ref readonly 메서드 반환에서 readonly 한정자는 메서드가 참조를 반환하고 해당 참조에 쓰기가 허용되지 않음을 나타냅니다.

읽기 전용 필드 예제

이 예에서 year 필드의 값은 클래스 생성자에서 할당되었지만 ChangeYear 메서드에서 변경할 수 없습니다.

class Age
{
    private readonly int _year;
    Age(int year)
    {
        _year = year;
    }
    void ChangeYear()
    {
        //_year = 1967; // Compile error if uncommented.
    }
}

다음 컨텍스트에서만 readonly 필드에 값을 할당할 수 있습니다.

  • 변수가 선언에서 초기화될 때. 예를 들면 다음과 같습니다.

    public readonly int y = 5;
    
  • 인스턴스 필드 선언을 포함하는 클래스의 인스턴스 생성자.

  • 정적 필드 선언을 포함하는 클래스의 정적 생성자.

또한 이러한 생성자 컨텍스트에서는 readonly 필드를 out 또는 ref 매개 변수로 전달하는 것이 유효합니다.

참고 항목

readonly 키워드와 const 키워드와 다릅니다. const 필드는 필드 선언에서만 초기화될 수 있습니다. 필드 선언과 임의 생성자에서 readonly 필드를 여러 번 할당할 수 있습니다. 따라서 readonly 필드는 사용된 생성자에 따라 다른 값을 가질 수 있습니다. 또한 const 필드는 컴파일 시간 상수인 반면, readonly 필드는 다음 예제와 같이 런타임 상수에 사용될 수 있습니다.

public static readonly uint timeStamp = (uint)DateTime.Now.Ticks;
public class SamplePoint
{
    public int x;
    // Initialize a readonly field
    public readonly int y = 25;
    public readonly int z;

    public SamplePoint()
    {
        // Initialize a readonly instance field
        z = 24;
    }

    public SamplePoint(int p1, int p2, int p3)
    {
        x = p1;
        y = p2;
        z = p3;
    }

    public static void Main()
    {
        SamplePoint p1 = new SamplePoint(11, 21, 32);   // OK
        Console.WriteLine($"p1: x={p1.x}, y={p1.y}, z={p1.z}");
        SamplePoint p2 = new SamplePoint();
        p2.x = 55;   // OK
        Console.WriteLine($"p2: x={p2.x}, y={p2.y}, z={p2.z}");
    }
    /*
     Output:
        p1: x=11, y=21, z=32
        p2: x=55, y=25, z=24
    */
}

위 예제에서 다음 예제와 같은 명령문을 사용하는 경우

p2.y = 66;        // Error

컴파일러 오류 메시지가 나타납니다.

읽기 전용 필드에는 할당할 수 없습니다. 단 생성자 또는 변수 이니셜라이저에서는 예외입니다.

읽기 전용 인스턴스 멤버

또한 readonly 한정자를 사용하여 인스턴스 멤버가 구조체의 상태를 수정하지 않는다고 선언할 수도 있습니다.

public readonly double Sum()
{
    return X + Y;
}

참고 항목

읽기/쓰기 속성의 경우 get 접근자에 readonly 한정자를 추가할 수 있습니다. 일부 get 접근자는 단순히 프라이빗 필드의 값을 반환하는 대신 계산을 수행하고 결과를 캐시할 수 있습니다. get 접근자에 readonly 한정자를 추가하면 get 접근자가 결과를 캐시하여 개체의 내부 상태를 수정하지 않도록 보장됩니다.

구조체 형식 문서의 readonly 인스턴스 멤버 섹션에서 더 많은 예를 찾을 수 있습니다.

참조 읽기 전용 반환 예

ref returnreadonly 한정자는 반환된 참조를 수정할 수 없음을 나타냅니다. 다음 예제는 원점에 대한 참조를 반환합니다. 예제에서는 readonly 한정자를 사용하여 호출자가 원본을 수정할 수 없음을 나타냅니다.

private static readonly SamplePoint s_origin = new SamplePoint(0, 0, 0);
public static ref readonly SamplePoint Origin => ref s_origin;

반환된 유형은 readonly struct일 필요는 없습니다. ref readonly를 통해 ref에서 반환될 수 있는 모든 형식을 반환할 수 있습니다.

읽기 전용 참조 읽기 전용 반환 예

ref readonly returnstruct 형식의 readonly 인스턴스 멤버와 함께 사용할 수도 있습니다.

public struct ReadonlyRefReadonlyExample
{
    private int _data;

    public readonly ref readonly int ReadonlyRefReadonly(ref int reference)
    {
        // _data = 1; // Compile error if uncommented.
        return ref reference;
    }
}

이 메서드는 기본적으로 readonly인 인스턴스 멤버(이 경우 메서드)와 함께 readonly 참조를 반환합니다(인스턴스 필드를 수정할 수 없음).

C# 언어 사양

자세한 내용은 C# 언어 사양을 참조하세요. 언어 사양은 C# 구문 및 사용법에 대 한 신뢰할 수 있는 소스 됩니다.

언어 사양 제안도 확인할 수 있습니다.

참고 항목