次の方法で共有


readonly (C# リファレンス)

readonly キーワードは、次の 5 つのコンテキストで使用できる修飾子です。

  • フィールド宣言では、readonlyは、フィールドへの割り当てが宣言の一部として、または同じクラス内のコンストラクター内でのみ行われることを示します。 読み取り専用フィールドは、フィールド宣言とコンストラクター内で複数回割り当ておよび再割り当てできます。

    コンストラクターが終了した後、 readonly フィールドを割り当てることはできません。 このルールは、値型と参照型に対して異なる影響を与えるものです。

    • 値型にはデータが直接含まれているため、 readonly 値型のフィールドは変更できません。
    • 参照型にはデータへの参照が含まれているため、 readonly 参照型のフィールドは常に同じオブジェクトを参照する必要があります。 そのオブジェクトは変更できない可能性があります。 readonly修飾子を使用すると、フィールド値を参照型の別のインスタンスに置き換えなくなります。 ただし、この修飾子では、フィールドのインスタンス データが読み取り専用フィールドによって変更されるのを防ぐことはありません。

    Warnung

    変更可能な参照型である外部から参照可能な読み取り専用フィールドを含む外部から参照可能な型は、セキュリティの脆弱性である可能性があり、"読み取り専用の変更可能な参照型を宣言しないでください" という警告 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;
}

読み取り/書き込みプロパティの場合は、readonly アクセサーにget修飾子を追加できます。 一部の get アクセサーは、単にプライベート フィールドの値を返すのではなく、計算を実行して結果をキャッシュできます。 readonly 修飾子を get アクセサーに追加することで、get アクセサーが結果をキャッシュすることによってオブジェクトの内部状態を変更しないことが保証されます。

その他の例については、readonlyに関する記事の インスタンス メンバー」セクションを参照してください。

参照読み取り時の戻り値の例

readonlyref 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から返すことができます。

readonly ref readonly 戻り値の例

ref readonly returnは、readonly型のインスタンスメンバー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# の構文と使用法の決定的なソースです。

言語仕様の提案を確認することもできます。

こちらも参照ください