次の方法で共有


init キーワード (C# リファレンス)

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

次のコードは、自動的に実装されるプロパティの init アクセサーを示しています。

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

パラメーターの検証を提供するには、アクセサーの 1 つを実装する必要がある場合があります。 これを行うには、C# 13 のプレビュー機能として導入された field キーワードを使用します。 field キーワードは、そのプロパティのコンパイラ合成バッキング フィールドにアクセスします。 次の例は、 init アクセサーが value パラメーターの範囲を検証するプロパティを示しています。

class Person_InitExampleFieldProperty
{
    public int YearOfBirth
    {
        get;
        init
        {
            field = (value <= DateTime.Now.Year)
                ? value
                : throw new ArgumentOutOfRangeException(nameof(value), "Year of birth can't be in the future");
        }
    }
}

重要

field キーワードは、C# 13 のプレビュー機能です。 fieldコンテキスト キーワードを使用するには、.NET 9 を使用し、<LangVersion>要素をプロジェクト ファイルにpreviewするように設定する必要があります。

field という名前のフィールドがあるクラスでは、field キーワード機能を使用する場合は注意が必要です。 新しい field キーワードは、プロパティ アクセサーのスコープ内の field という名前のフィールドをシャドウします。 field変数の名前を変更するか、@ トークンを使用してfield識別子を@fieldとして参照できます。 詳細については、field キーワード機能の仕様を参照してください。

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

class Person_InitExampleExpressionBodied
{
    private int _yearOfBirth;

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

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

class Person_InitExample
{
     private int _yearOfBirth;

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

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;
    }
}

次の例は、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# の構文と使用法に関する信頼性のある情報源です。

関連項目