다음을 통해 공유


readonly(C# 참조)

readonly 키워드는 5가지 컨텍스트에서 사용할 수 있는 한정자입니다.

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

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

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

    경고

    변경 가능한 참조 형식인 외부에 표시되는 읽기 전용 필드를 포함하는 외부에 표시되는 형식은 보안 취약성일 수 있으며 경고 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 또는 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;
}

비고

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

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

참조 읽기 전용 값을 반환하는 예제

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

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

반환된 형식이 readonly struct일 필요는 없습니다. ref이(가) 반환할 수 있는 모든 형식을 ref readonly이(가) 반환할 수 있습니다.

읽기 전용 ref 읽기 전용 반환 예시

A ref readonly returnreadonly 형식의 인스턴스 멤버와 함께 struct을 사용할 수 있습니다.

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# 구문 및 사용의 최종 소스입니다.

언어 사양 제안도 볼 수 있습니다.

참고하십시오