init (C# リファレンス)

init キーワードによってプロパティ内またはインデクサー内で "アクセサー" メソッドが定義されます。 init のみのセッターでは、オブジェクトの構築時のみ、プロパティまたはインデクサー要素に値が割り当てられます。 init は不変性を強制するため、オブジェクトが一度初期化されると変更できなくなります。 init アクセサーを使用すると、呼び出し元のコードで オブジェクト初期化子 を使用して初期値を設定できます。 これに対し、get セッターのみを持つ自動実装プロパティは、コンストラクターを呼び出して初期化する必要があります。 private set アクセサーを持つプロパティは、クラス内でのみ構築後に変更できます。

次の例では、YearOfBirth という名前のプロパティの get アクセサーと init アクセサーを定義しています。 また、_yearOfBirth という名前のプライベート フィールドを使って、プロパティの値を戻しています。

class Person_InitExample
{
     private int _yearOfBirth;

     public int YearOfBirth
     {
         get { return _yearOfBirth; }
         init { _yearOfBirth = value; }
     }
}

多くの場合、前の例のように、init アクセサーは値を割り当てる 1 つのステートメントで構成されます。 init のため、次に示す例は機能しません。

var john = new Person_InitExample
{
    YearOfBirth = 1984
};

john.YearOfBirth = 1926; //Not allowed, as its value can only be set once in the constructor

init アクセサーは、呼び出し元にプロパティの設定を強制しません。 代わりに、呼び出し元がオブジェクトのイニシャライザーを使用できるようにしながら、後から変更することを禁止します。 ユーザーは、required 修飾子を追加して、呼び出し元にプロパティの設定を強制できます。 次の例は、バッキング フィールドとして null 許容値型を持つ init 専用のプロパティを示しています。 呼び出し元が YearOfBirth プロパティを初期化しない場合、そのプロパティには既定の null 値が設定されます。

class Person_InitExampleNullability
{
    private int? _yearOfBirth;

    public int? YearOfBirth
    {
        get => _yearOfBirth;
        init => _yearOfBirth = value;
    }
}

呼び出し元に最初の null 以外の値を強制的に設定するには、次の例に示すように、 required 修飾子を追加してください。

class Person_InitExampleNonNull
{
    private int _yearOfBirth;

    public required int YearOfBirth
    {
        get => _yearOfBirth;
        init => _yearOfBirth = value;
    }
}

init アクセサーは、式形式のメンバーとして使用できます。 例:

class Person_InitExampleExpressionBodied
{
    private int _yearOfBirth;

    public int YearOfBirth
    {
        get => _yearOfBirth;
        init => _yearOfBirth = value;
    }
}

次のコード例に示すように、init アクセサーは、自動実装プロパティでも使用できます。

class Person_InitExampleAutoProperty
{
    public int YearOfBirth { get; init; }
}

次の例は、private set、read only、init プロパティの違いを示しています。 プライベート セット バージョンと読み取り専用バージョンは両方とも、呼び出し元が追加されたコンストラクターを使用して name プロパティを設定する必要があります。 この private set バージョンでは、ユーザーは、インスタンスの構築後に名前を変更できます。 init バージョンにコンストラクターは必要ありません。 呼び出し元は、オブジェクト初期化子を使用してプロパティを初期化できます。

class PersonPrivateSet
{
    public string FirstName { get; private set; }
    public string LastName { get; private set; }
    public PersonPrivateSet(string first, string last) => (FirstName, LastName) = (first, last);

    public void ChangeName(string first, string last) => (FirstName, LastName) = (first, last);
}

class PersonReadOnly
{
    public string FirstName { get; }
    public string LastName { get; }
    public PersonReadOnly(string first, string last) => (FirstName, LastName) = (first, last);
}

class PersonInit
{
    public string FirstName { get; init; }
    public string LastName { get; init; }
}
PersonPrivateSet personPrivateSet = new("Bill", "Gates");
PersonReadOnly personReadOnly = new("Bill", "Gates");
PersonInit personInit = new() { FirstName = "Bill", LastName = "Gates" };

C# 言語仕様

詳細については、「C# 言語の仕様」を参照してください。 言語仕様は、C# の構文と使用法に関する信頼性のある情報源です。

関連項目