なんかいろいろと書いてくブログ

関東のどこかで働く、一般人

【C#】init アクセサーについてのメモ

初めに

C# 9.0 使用できるという噂の init アクセサー この前、しれっと CTO から
.Net FrameWork を引き上げるといわれた
引き上げに伴い、C# 9.0が使用できるようなるようになるので メモ

公式ドキュメント

知りたいことはすべて公式に書いてある

docs.microsoft.com

アクセサーについて

C# 8.0 以前の話

C#8.0 以前では model 定義の際には

public class HogeClass
{
  public string hoge { get; set; }
}

のように、値取得のためのgetアクセサーと値を格納するためのsetアクセサーを使用できた
ただし、setをつけると後から値が変更されてしまい、具合がよくないので
読み込み専用の model として

public class HogeClass
{
  public string hoge { get; set; }

  // getだけでは値の更新はできないので、コンストラクタ―で値を設定する
  public HogeClass (string hoge)
  {
    this.hoge = hoge
  }
}

public class Program
{
  // hogeClass実装時に、hogeにstring型の"hogehoge"を設定する
  var hogeClass = new HogeClass("hogehoge")

  var hoge = hogeClass.hoge

  hogeClass.hoge = "hogehoge2" // NG setアクセサーがないので再度の設定はできない

}

と、書いていた
ちなみに、set アクセサーがないとオブジェクト初期化子も使用できないので、

public class Program
{
  var hogeClass = new HogeClass{ hoge = "hogehoge" } // NG
}

もできないといった制約があった

init アクセサーについて

C# 9.0 からはオブジェクト初期化子のみで値の設定ができる、initが使用できるとのこと 書き方は簡単で、set アクセサーの変わりにinit を使用するだけで

public class HogeClass
{
  public string hoge { get; init; }

  // 必須ではない
  // public HogeClass (string hoge)
  // {
  //   this.hoge = hoge
  // }
}

public class Program
{
  var hogeClass = new HogeClass{ hoge = "hogehoge" }


  hogeClass.hoge = "hogehoge2" // NG 初期化時のみ値の設定ができる

}

このように書くことができる init なら、初期化後の意図しない値の変更が防げるだけでなく

  public HogeClass (string hoge)
  {
    this.hoge = hoge
  }

も不要となる(はず)
※ 記載時点では未検証 ↓ちゃんと検証した 【C#】init アクセサーについてのメモ - Qiita

終わりに

コードがスッキリする & 柔軟な実装ができる(コンストラクタと初期化で値設定ができる)
プロダクトコードでも init を使うことが多くなりそうな雰囲気がある