'readonly' と 'const' キーワード
CoddyのC#ジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 16/70。
C#には、変更できない値を作成するための2つのキーワード、constとreadonlyが用意されています。どちらも変更を防ぐものですが、動作が異なり、目的も異なります。
const フィールドは宣言時に割り当てられる必要があり、その値はコンパイル時に決定されます。これは暗黙的に static であり、インスタンスではなくクラスに属することを意味します:
public class GameSettings
{
public const int MaxPlayers = 4;
public const double Gravity = 9.81;
}定数にはクラス名を通じてアクセスします: GameSettings.MaxPlayers。コンパイラが正確な値を知る必要があるため、定数はプリミティブ型、文字列、およびnullでのみ機能します。
readonly フィールドは、宣言時またはコンストラクタ内で割り当てることができ、その値は実行時に決定されます。
public class Player
{
public readonly string Id;
public readonly DateTime CreatedAt = DateTime.Now;
public Player(string id)
{
Id = id;
}
}const とは異なり、readonly フィールドは任意の型を保持でき、インスタンスごとに異なる値を持つことができます。コンストラクタが終了すると、その値を変更することはできません。
数学的な定数のように、真に普遍的で決して変わることのない値には const を使用します。一度だけ設定されるべきですが、オブジェクト間で異なったり、実行時の計算が必要だったりする値には readonly を使用します。
チャレンジ
簡単普遍的な定数には const を使用し、実行時に一度だけ設定される値には readonly を使用する場面を示す、物理シミュレーション設定システムを構築しましょう。
コードを整理するために、2つのファイルを作成します:
PhysicsConstants.cs:Simulation名前空間にPhysicsConstantsクラスを定義します。このクラスには、決して変更されず、どこでも同じである普遍的な定数を含める必要があります:9.81に設定されたconstフィールドGravity299792458に設定されたconstフィールドSpeedOfLight"m/s^2"に設定されたconst文字列GravityUnit
Projectile.cs:Simulation名前空間にProjectileクラスを定義します。各発射体(projectile)は、作成時に一度だけ設定され、その後は決して変更されない値を持っています:readonlyフィールドName(string)readonlyフィールドInitialVelocity(double)readonlyフィールドLaunchAngle(double、度単位)- これら3つの値をすべて受け取り、設定するコンストラクタ
- 次の公式を使用して最大高度を計算するメソッド
GetMaxHeight():(velocity^2 * sin^2(angle)) / (2 * gravity)。Math.Sin()を使用し、Math.PI / 180を掛けることで度をラジアンに変換してください。
Program.cs: メインファイルで、入力値を使用して発射体を作成し、物理定数と発射体の計算された最大高度を表示します。
3つの入力を受け取ります:
- 発射体の名前 (Projectile name)
- 初速度 (Initial velocity、m/s単位)
- 発射角度 (Launch angle、度単位)
出力を次の形式で表示してください:
Gravity: {Gravity} {GravityUnit}
Speed of Light: {SpeedOfLight} m/s
Projectile: {Name}
Initial Velocity: {InitialVelocity} m/s
Launch Angle: {LaunchAngle} degrees
Max Height: {maxHeight} mMath.Round(value, 2) を使用して、最大高度を小数点以下2桁に丸めてください。
例えば、入力が Rocket、50、45 の場合、出力は次のようになります:
Gravity: 9.81 m/s^2
Speed of Light: 299792458 m/s
Projectile: Rocket
Initial Velocity: 50 m/s
Launch Angle: 45 degrees
Max Height: 63.71 mチートシート
C# には、不変の値を作成するための 2 つのキーワード const と readonly が用意されています。
const フィールドは宣言時に割り当てる必要があり、コンパイル時に決定されます。また、暗黙的に static となります。
public class GameSettings
{
public const int MaxPlayers = 4;
public const double Gravity = 9.81;
}定数にはクラス名を通じてアクセスします:GameSettings.MaxPlayers。定数は、プリミティブ型、文字列、および null でのみ機能します。
readonly フィールドは、宣言時またはコンストラクタ内で割り当てることができ、その値は実行時に決定されます。
public class Player
{
public readonly string Id;
public readonly DateTime CreatedAt = DateTime.Now;
public Player(string id)
{
Id = id;
}
}readonly フィールドは任意の型を保持でき、インスタンスごとに異なる値を持つことができます。コンストラクタが終了すると、値を変更することはできません。
決して変わることのない普遍的な値には const を使用します。一度だけ設定する必要があるが、オブジェクトごとに異なる可能性がある値や、実行時の計算が必要な値には readonly を使用します。
自分で試してみよう
using System;
using Simulation;
class Program
{
public static void Main(string[] args)
{
// 入力を読み込む
string name = Console.ReadLine();
double velocity = Convert.ToDouble(Console.ReadLine());
double angle = Convert.ToDouble(Console.ReadLine());
// TODO: 入力値を使用して Projectile オブジェクトを作成する
// TODO: 物理定数(単位付きの Gravity、Speed of Light)を出力する
// TODO: 発射体の情報(Name、Initial Velocity、Launch Angle)を出力する
// TODO: 最大到達高度を計算して出力する(小数点以下2桁に丸める)
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。