readonly (C# リファレンス)readonly (C# Reference)

readonly キーワードは、3 つのコンテキストで使用できる修飾子です。The readonly keyword is a modifier that can be used in three contexts:

  • フィールドの宣言では、readonly は、フィールドへの割り当てが、宣言の一部として、または同じクラスのコンストラクター内でのみ可能であることを示します。In a field declaration, readonly indicates that assignment to the field can only occur as part of the declaration or in a constructor in the same class. readonly フィールドは、フィールドの宣言とコンストラクターで複数回割り当ておよび再割り当てを行うことができます。A readonly field can be assigned and reassigned multiple times within the field declaration and constructor.

    readonly フィールドは、コンストラクターが終了した後で割り当てることはできません。A readonly field cannot be assigned after the constructor exits. 値型と参照型では意味が異なります。That has different implications for value types and reference types:

    • 値型にはそのデータが直接含まれるため、readonly 値型のフィールドは変更できません。Because value types directly contain their data, a field that is a readonly value type is immutable.
    • 参照型にはそのデータへの参照が含まれるため、readonly 参照型のフィールドは、常に同じオブジェクトを参照する必要があります。Because reference types contain a reference to their data, a field that is a readonly reference type must always refer to the same object. そのオブジェクトは不変ではありません。That object is not immutable. readonly 修飾子があると、フィールドを参照型の別のインスタンスで置き換えることはできません。The readonly modifier prevents the field from being replaced by a different instance of the reference type. ただし、フィールドのインスタンス データを読み取り専用フィールドで変更することは禁止されません。However, the modifier does not prevent the instance data of the field from being modified through the read-only field.

    警告

    変更可能な参照型である外部から参照できる読み取り専用フィールドを含む外部から参照できる型はセキュリティの脆弱性があり、警告 CA2104 がトリガーされる可能性があります: "読み取り専用の変更可能な参照型を宣言しません"。An externally visible type that contains an externally visible read-only field that is a mutable reference type may be a security vulnerability and may trigger warning CA2104 : "Do not declare read only mutable reference types."

  • readonly struct の定義では、readonlystruct が変更不可であることを示します。In a readonly struct definition, readonly indicates that the struct is immutable.

  • ref readonly メソッドの戻り値では、readonly 修飾子は、メソッドが参照を返し、その参照への書き込みが許可されないことを示します。In a ref readonly method return, the readonly modifier indicates that method returns a reference and writes are not allowed to that reference.

最後の 2 つのコンテキストは、C# 7.2 で追加されました。The final two contexts were added in C# 7.2.

読み取り専用フィールドの例Readonly field example

この例では、year フィールドの値は、クラス コンストラクターで値が割り当てられていても ChangeYear メソッドでは変更できません。In this example, the value of the field year cannot be changed in the method ChangeYear, even though it is assigned a value in the class constructor:

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

readonly のフィールドに値を割り当てることができるのは、次のコンテキスト内に限られます。You can assign a value to a readonly field only in the following contexts:

  • 値が宣言で初期化される場合。次に例を示します。When the variable is initialized in the declaration, for example:

    public readonly int y = 5;
    
  • インスタンス フィールド宣言を含むクラスのインスタンス コンストラクター内。In an instance constructor of the class that contains the instance field declaration.

  • 静的フィールド宣言を含むクラスの静的コンストラクター内。In the static constructor of the class that contains the static field declaration.

また、これらのコンストラクター コンテキスト内でのみ、readonly フィールドを out パラメーターまたは ref パラメーターとして渡すことができます。These constructor contexts are also the only contexts in which it is valid to pass a readonly field as an out or ref parameter.

注意

readonly キーワードは const キーワードとは異なります。The readonly keyword is different from the const keyword. const フィールドは、フィールドの宣言でしか初期化できません。A const field can only be initialized at the declaration of the field. readonly フィールドは、フィールドの宣言と任意のコンストラクターで複数回割り当てることができます。A readonly field can be assigned multiple times in the field declaration and in any constructor. このため、readonly フィールドは、使用するコンストラクターに応じて異なる値を持つことができます。Therefore, readonly fields can have different values depending on the constructor used. また、次の例のように、const フィールドがコンパイル時定数であるのに対し、readonly フィールドは実行時定数として使用できます。Also, while a const field is a compile-time constant, the readonly field can be used for runtime constants as in the following example:

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

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

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

    public static void Main()
    {
        SampleClass p1 = new SampleClass(11, 21, 32);   // OK
        Console.WriteLine($"p1: x={p1.x}, y={p1.y}, z={p1.z}");
        SampleClass p2 = new SampleClass();
        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
    */
}

上の例で、次の例のようなステートメントを使うものとします。In the preceding example, if you use a statement like the following example:

p2.y = 66;        // Error

この場合、次のコンパイル エラー メッセージが表示されます。you will get the compiler error message:

A readonly field cannot be assigned to (except in a constructor or a variable initializer)

読み取り専用の構造体の例Readonly struct example

struct 定義での readonly 修飾子は、構造体が変更不可であることを宣言します。The readonly modifier on a struct definition declares that the struct is immutable. 次の例のように、struct のすべてのインスタンス フィールドを readonly とマークする必要があります。Every instance field of the struct must be marked readonly, as shown in the following example:

public readonly struct Point
{
    public double X { get; }
    public double Y { get; }

    public Point(double x, double y) => (X, Y) = (x, y);

    public override string ToString() => $"({X}, {Y})";
}

前の例では、読み取り専用の自動プロパティを使ってその記憶域を宣言しています。The preceding example uses readonly auto properties to declare its storage. これは、これらのプロパティに対して readonly バッキング フィールドを作成するようコンパイラに指示します。That instructs the compiler to create readonly backing fields for those properties. readonly フィールドを直接宣言することもできます。You could also declare readonly fields directly:

public readonly struct Point
{
    public readonly double X;
    public readonly double Y;

    public Point(double x, double y) => (X, Y) = (x, y);

    public override string ToString() => $"({X}, {Y})";
}

readonly に指定されていないフィールドを追加すると、コンパイラ エラー CS8340:"読み取り専用の構造体のインスタンス フィールドは、読み取り専用である必要があります" が生成されます。Adding a field not marked readonly generates compiler error CS8340: "Instance fields of readonly structs must be readonly."

ref readonly の戻り値の例Ref readonly return example

ref return での readonly 修飾子は、返される参照を変更できないことを示します。The readonly modifier on a ref return indicates that the returned reference cannot be modified. 次の例は、origin に参照を返します。The following example returns a reference to the origin. readonly 修飾子を使用して、呼び出し元が origin を変更できないことを示しています。It uses the readonly modifier to indicate that callers cannot modify the origin:

private static readonly Point origin = new Point(0, 0);
public static ref readonly Point Origin => ref origin;

返される型を readonly struct にする必要はありません。The type returned doesn't need to be a readonly struct. ref で返すことができる任意の型を、ref readonly で返すことができます。Any type that can be returned by ref can be returned by ref readonly.

C# 言語仕様C# language specification

詳細については、「C# 言語の仕様」を参照してください。For more information, see the C# Language Specification. 言語仕様は、C# の構文と使用法に関する信頼性のある情報源です。The language specification is the definitive source for C# syntax and usage.

関連項目See also