LoginSignup
10
3

More than 1 year has passed since last update.

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

Last updated at Posted at 2022-01-23

blogで雑にまとめたC# 9.0から使えるinit アクセサーについて、
ちゃんと検証したので記事にした

公式ドキュメント

公式は正義
https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/classes-and-structs/properties

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

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

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

public class GetOnlyClass
{
    public string? property { get; }

    public GetOnlyClass()
    {
    }
    public GetOnlyClass(string property)
    {
        this.property = property;
    }
}

// get の場合はコンストラクタで値を設定する
var getOnlyClass = new GetOnlyClass("hoge");
Console.WriteLine(getOnlyClass.property);

// getOnlyClass.property = "fuga"; // NG 値の更新はできない

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

var getOnlyClass = new GetOnlyClass { property = "hoge" }; // NG

もできないといった制約があった
↓のように、読み取り専用だよって言われる
image.png

init アクセサーについて

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

public class InitClass
{
    public string? property { get; init; }
}

// オブジェクト初期化子で値の設定ができる
var initClass = new InitClass { property = "hoge"};

ちなみに、↑の状態でコンストラクタ内で値を設定しようとすると
怒られる

image.png

ので、コンストラクタを書けば、コンストラクタでの値の設定をすることができる

public class InitCconstructorClass
{
    public string? property { get; init; }

    // 引数なしのコンストラクタを定義する
    public InitCconstructorClass()
    {
    }

    public InitCconstructorClass(string property)
    {
        this.property = property;
    }
}

この書き方なら、コンストラクタと初期化時両方で値の設定ができる(かつ、後で変更ができない)
ので、get onlyよりも使い勝手がよい

10
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
3