search
LoginSignup
3
Help us understand the problem. What are the problem?

posted at

updated at

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

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よりも使い勝手がよい

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
What you can do with signing up
3
Help us understand the problem. What are the problem?