readonly (C# リファレンス)
readonly
キーワードは、次の 5 つのコンテキストで使用できる修飾子です。
フィールドの宣言では、
readonly
は、フィールドへの割り当てが、宣言の一部として、または同じクラスのコンストラクター内でのみ可能であることを示します。 readonly フィールドは、フィールドの宣言とコンストラクターで複数回割り当ておよび再割り当てを行うことができます。readonly
フィールドは、コンストラクターが終了した後で割り当てることはできません。 この規則は、値型と参照型では意味が異なります。- 値型にはそのデータが直接含まれるため、
readonly
値型のフィールドは変更できません。 - 参照型にはそのデータへの参照が含まれるため、
readonly
参照型のフィールドは、常に同じオブジェクトを参照する必要があります。 そのオブジェクトは変更不可ではない可能性があります。readonly
修飾子は、フィールド値を参照型の別のインスタンスに置き換えることを防ぎます。 ただし、フィールドのインスタンス データを読み取り専用フィールドで変更することは禁止されません。
警告
変更可能な参照型である外部から参照できる読み取り専用フィールドを含む外部から参照できる型はセキュリティの脆弱性があり、警告 CA2104 がトリガーされる可能性があります: "読み取り専用の変更可能な参照型を宣言しません"。
- 値型にはそのデータが直接含まれるため、
readonly struct
型定義では、readonly
は構造体型が変更不可であることを示します。 詳細については、「構造体型」の記事の「readonly
構造体」セクションを参照してください。構造体型内のインスタンス メンバー宣言では、
readonly
は、インスタンス メンバーによって構造体の状態が変更されないことを示します。 詳細については、構造体型に関する記事の「readonly
インスタンス メンバー」セクションを参照してください。ref readonly
メソッドの戻り値では、readonly
修飾子は、メソッドが参照を返し、その参照への書き込みが許可されないことを示します。- メソッドに
ref 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 インスタンスのメンバー
readonly
修飾子を使って、インスタンス メンバーで構造体の状態を変更しないことを宣言することもできます。
public readonly double Sum()
{
return X + Y;
}
Note
読み取り/書き込みプロパティの場合は、readonly
修飾子を get
アクセサーに追加できます。 一部の get
アクセサーは、プライベート フィールドの値を単に返すのではなく、計算を実行して結果をキャッシュする場合があります。 readonly
修飾子を get
アクセサーに追加すると、get
アクセサーが結果をキャッシュすることでオブジェクトの内部状態を変更しないことが保証されます。
その他の例については、「構造体の種類」の記事の「readonly
インスタンス メンバー」セクションを参照してください。
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
で返すことができます。
Readonly ref readonly の戻り値の例
ref readonly return
は、struct
型の 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# の構文と使用法に関する信頼性のある情報源です。
言語仕様の提案を参照することもできます。
関連項目
.NET