フィールド (C# プログラミング ガイド)

フィールドとは、クラスまたは構造体で直接宣言される任意の型の変数です。 フィールドは、それを含んでいる型のメンバーです。

クラスまたは構造体には、インスタンス フィールドと静的フィールドのいずれか、またはその両方が含まれる場合があります。 インスタンス フィールドは、型のインスタンスに固有です。 たとえば、クラス T と、そのクラスのインスタンス フィールド F があるとします。型 T のオブジェクトを 2 つ作成した場合、他方のオブジェクトの値に影響を与えることなく、各オブジェクトの F の値を変更できます。 これとは対照的に静的フィールドは型自体に属し、その型のすべてのインスタンスで共有されます。 静的フィールドは、型名を使用してのみアクセスできます。 インスタンス名を使用して静的フィールドにアクセスすると、CS0176 コンパイル時エラーが発生します。

一般に、フィールドに対する private または protected のアクセシビリティを宣言する必要があります。 型からクライアント コードに公開するデータは、メソッドプロパティインデクサーを使用して提供する必要があります。 これらの構成要素を使用して、内部フィールドに間接的にアクセスすることで、無効な値が入力されることを防止できます。 パブリック プロパティによって公開されるデータを格納するプライベート フィールドは、バッキング ストアまたはバッキング フィールドと呼ばれます。 public フィールドを宣言することもできますが、その場合、その型を使うコードで、そのフィールドを不正な値に設定することや、オブジェクトのデータを変更することを防ぐことができません。

一般に、フィールドには、複数の型メソッドからアクセスでき、1 つのメソッドの有効期間より長く保持されるデータが格納されます。 たとえば、暦の日付を表す型には、3 つの整数フィールド、月、日、年がある場合があります。 1 つのメソッドのスコープ外で使用されることのない変数は、メソッド本体内で "ローカル変数" として宣言する必要があります。

フィールドは、フィールドのアクセス レベル、型、名前の順に指定して、クラスまたは構造体のブロック内で宣言します。 以下に例を示します。

public class CalendarEntry
{

    // private field (Located near wrapping "Date" property).
    private DateTime _date;

    // Public property exposes _date field safely.
    public DateTime Date
    {
        get
        {
            return _date;
        }
        set
        {
            // Set some reasonable boundaries for likely birth dates.
            if (value.Year > 1900 && value.Year <= DateTime.Today.Year)
            {
                _date = value;
            }
            else
            {
                throw new ArgumentOutOfRangeException("Date");
            }
        }
    }

    // public field (Generally not recommended).
    public string? Day;

    // Public method also exposes _date field safely.
    // Example call: birthday.SetDate("1975, 6, 30");
    public void SetDate(string dateString)
    {
        DateTime dt = Convert.ToDateTime(dateString);

        // Set some reasonable boundaries for likely birth dates.
        if (dt.Year > 1900 && dt.Year <= DateTime.Today.Year)
        {
            _date = dt;
        }
        else
        {
            throw new ArgumentOutOfRangeException("dateString");
        }
    }

    public TimeSpan GetTimeSpan(string dateString)
    {
        DateTime dt = Convert.ToDateTime(dateString);

        if (dt.Ticks < _date.Ticks)
        {
            return _date - dt;
        }
        else
        {
            throw new ArgumentOutOfRangeException("dateString");
        }
    }
}

インスタンス内のフィールドにアクセスするには、instancename._fieldName のように、インスタンス名の後にピリオドを追加し、その後にフィールド名を続けます。 次に例を示します。

CalendarEntry birthday = new CalendarEntry();
birthday.Day = "Saturday";

フィールドには、フィールドの宣言時に代入演算子を使用して初期値を指定できます。 たとえば、Day フィールドに "Monday" を自動的に代入するには、次の例のように Day を宣言します。

public class CalendarDateWithInitialization
{
    public string Day = "Monday";
    //...
}

フィールドは、オブジェクト インスタンスのコンストラクターが呼び出される直前に初期化されます。 コンストラクターがフィールドの値を代入すると、フィールドの宣言時に指定された値はすべて上書きされます。 詳細については、「コンストラクターの使用」を参照してください。

注意

フィールドの初期化子は、他のインスタンス フィールドを参照できません。

フィールドには publicprivateprotectedinternalprotected internalprivate protected のいずれかをマークできます。 これらのアクセス修飾子により、型のユーザーがフィールドにアクセスする方法が定義されます。 詳細については、「アクセス修飾子」を参照してください。

必要に応じて、フィールドをstaticに宣言することもできます。 その型のインスタンスが存在しなくても、呼び出し元はいつでも静的フィールドを使用できます。 詳細については、「静的クラスと静的クラス メンバー」を参照してください。

フィールドは readonly と宣言できます。 読み取り専用フィールドには、初期化時またはコンストラクターによる以外は、値を代入できません。 static readonly フィールドは定数と似ていますが、C# コンパイラが静的な読み取り専用フィールドの値にアクセスできるのは実行時のみで、コンパイル時はアクセスできない点が異なります。 詳細については、「定数」を参照してください。

フィールドは required と宣言できます。 必須フィールドは、コンストラクター、またはオブジェクトの作成時にオブジェクト初期化子によって初期化する必要があります。 必要なすべてのメンバーを初期化する任意のコンストラクター宣言に System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute 属性を追加します。

required 修飾子を同じフィールドの readonly 修飾子と組み合わせることはできません。 ただし、プロパティrequiredinit のみにすることができます。

C#12 以降、プライマリ コンストラクター パラメーターは、フィールドを宣言する代わりに使用できるようになりました。 初期化時に用意する必要がある依存関係が型にある場合、それらの依存関係を用意するプライマリ コンストラクターを作成できます。 これらのパラメーターを取り込み、型内で宣言されたフィールドの代わりに使用できます。 record 型の場合、プライマリ コンストラクター パラメーターはパブリック プロパティとして表示されます。

C# 言語仕様

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

関連項目