readonly (C# リファレンス)
readonly
キーワードは、次の 4 つのコンテキストで使用できる修飾子です。
フィールドの宣言では、
readonly
は、フィールドへの割り当てが、宣言の一部として、または同じクラスのコンストラクター内でのみ可能であることを示します。 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
フィールドを 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
この場合、次のコンパイル エラー メッセージが表示されます。
読み取り専用フィールドに割り当てることはできません (コンストラクター、変数初期化子では可)
ref readonly の戻り値の例
ref return
での readonly
修飾子は、返される参照を変更できないことを示します。 次の例は、origin に参照を返します。 readonly
修飾子を使用して、呼び出し元が origin を変更できないことを示しています。
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
で返すことができます。
C# 言語仕様
詳細については、「C# 言語の仕様」を参照してください。 言語仕様は、C# の構文と使用法に関する信頼性のある情報源です。
言語仕様の提案を参照することもできます。