Menu
Coddy logo textTech

'readonly' と 'const' キーワード

CoddyのC#ジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 16/70。

C#には、変更できない値を作成するための2つのキーワード、constreadonlyが用意されています。どちらも変更を防ぐものですが、動作が異なり、目的も異なります。

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 を使用します。

challenge icon

チャレンジ

簡単

普遍的な定数には const を使用し、実行時に一度だけ設定される値には readonly を使用する場面を示す、物理シミュレーション設定システムを構築しましょう。

コードを整理するために、2つのファイルを作成します:

  • PhysicsConstants.cs: Simulation 名前空間に PhysicsConstants クラスを定義します。このクラスには、決して変更されず、どこでも同じである普遍的な定数を含める必要があります:
    • 9.81 に設定された const フィールド Gravity
    • 299792458 に設定された 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} m

Math.Round(value, 2) を使用して、最大高度を小数点以下2桁に丸めてください。

例えば、入力が Rocket5045 の場合、出力は次のようになります:

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 つのキーワード constreadonly が用意されています。

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桁に丸める)
    }
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン