本文へスキップ
BecomeCoder

C#オブジェクト指向コース · 第5章 オブジェクト指向の実践テクニック · レッスン34

init専用プロパティと required メンバー

ブラウザで完結

導入

「生成したら二度と変わらない」オブジェクトは安全です。でもコンストラクタに引数を10個も並べるのは読みにくい。init は「生成時だけ設定できる」プロパティを、required は「設定し忘れを禁止する」しくみを提供します。

図解

flowchart LR
    N["new User { Name = ... }"] -->|生成時のみ設定可| P["Name { get; init; }"]
    P -.->|生成後は変更不可| X["u.Name = ... ✗ コンパイルエラー"]
    style P fill:#e1f5fe

サンプル

var u = new User { Name = "Taro", Age = 20 };
Console.WriteLine($"{u.Name} {u.Age}");   // Taro 20

// u.Name = "Jiro";   // ← init なので生成後は代入できない(コンパイルエラー)

class User
{
    public required string Name { get; init; }  // 設定必須・生成時のみ
    public int Age { get; init; }               // 任意・生成時のみ
}
  • init は「オブジェクト初期化子の中でだけ設定できる」セッター(生成後は不変)
  • required は「初期化子で必ず設定せよ」を強制する(付け忘れをコンパイラが検出)
  • コンストラクタを増やさずに、安全な不変オブジェクトを作れる

やってみよう

Name を設定せずに new User { Age = 20 } と書くとどうなるか、u.Age = 30 と後から代入するとどうなるかを試して、コンパイラの指摘を読んでみましょう。

演習

var p = new Product { Name = "Pen", Price = 120 };
Console.WriteLine($"{p.Name}: {p.Price}");   // Pen: 120

// TODO: Name を required かつ init、Price を init のプロパティにした Product を定義してください
___
  • 期待される出力: Pen: 120
ヒント1を見る

class Product { public required string Name { get; init; } public int Price { get; init; } }

ヒント2を見る

required は「初期化子で必ず設定」、init は「生成時のみ設定可」を意味します

まとめ

  • init は生成時だけ設定できる不変プロパティ
  • required は設定必須を強制し、付け忘れを防ぐ
  • コンストラクタを膨らませずに安全なオブジェクトを作れる

次回: オブジェクトとコレクションを簡潔に作る「初期化子」です。

実際に動かしてみよう

本文のサンプルや演習のコードは、コードブロック右上の「コピー」ボタンでコピーして、下のエディタに貼り付ければそのまま実行できます。

C# — ブラウザ内で実行

ブラウザ内でC#を動かす環境を読み込みます(初回のみ数秒)。
スクロールして表示された時点でも自動で読み込まれます。