次の方法で共有


インスタンス コンストラクター (C# プログラミング ガイド)

インスタンス コンストラクターを宣言して、 newを使用して型の新しいインスタンスを作成するときに実行されるコードを指定します。 非静的クラスの 静的 クラスまたは静的変数を初期化するには、 静的コンストラクターを定義できます。

次の例に示すように、1 つの型で複数のインスタンス コンストラクターを宣言できます。

class Coords
{
    public Coords()
        : this(0, 0)
    {  }

    public Coords(int x, int y)
    {
        X = x;
        Y = y;
    }

    public int X { get; set; }
    public int Y { get; set; }

    public override string ToString() => $"({X},{Y})";
}

class Example
{
    static void Main()
    {
        var p1 = new Coords();
        Console.WriteLine($"Coords #1 at {p1}");
        // Output: Coords #1 at (0,0)

        var p2 = new Coords(5, 3);
        Console.WriteLine($"Coords #2 at {p2}");
        // Output: Coords #2 at (5,3)
    }
}

前の例では、1 番目のパラメーターなしのコンストラクターは、両方の引数が 0等しい 2 番目のコンストラクターを呼び出します。 これを行うには、 this キーワードを使用します。

派生クラスでインスタンス コンストラクターを宣言する場合は、基底クラスのコンストラクターを呼び出すことができます。 これを行うには、次の例に示すように、 base キーワードを使用します。

abstract class Shape
{
    public const double pi = Math.PI;
    protected double x, y;

    public Shape(double x, double y)
    {
        this.x = x;
        this.y = y;
    }

    public abstract double Area();
}

class Circle : Shape
{
    public Circle(double radius)
        : base(radius, 0)
    {  }

    public override double Area() => pi * x * x;
}

class Cylinder : Circle
{
    public Cylinder(double radius, double height)
        : base(radius)
    {
        y = height;
    }

    public override double Area() => (2 * base.Area()) + (2 * pi * x * y);
}

class Example
{
    static void Main()
    {
        double radius = 2.5;
        double height = 3.0;

        var ring = new Circle(radius);
        Console.WriteLine($"Area of the circle = {ring.Area():F2}");
        // Output: Area of the circle = 19.63
        
        var tube = new Cylinder(radius, height);
        Console.WriteLine($"Area of the cylinder = {tube.Area():F2}");
        // Output: Area of the cylinder = 86.39
    }
}

パラメーターなしのコンストラクター

クラスに明示的なインスタンス コンストラクターがない場合、次の例に示すように、C# には、そのクラスのインスタンスをインスタンス化するために使用できるパラメーターなしのコンストラクターが用意されています。

public class Person
{
    public int age;
    public string name = "unknown";
}

class Example
{
    static void Main()
    {
        var person = new Person();
        Console.WriteLine($"Name: {person.name}, Age: {person.age}");
        // Output:  Name: unknown, Age: 0
    }
}

このコンストラクターは、対応する初期化子に従ってインスタンス フィールドとプロパティを初期化します。 フィールドまたはプロパティに初期化子がない場合、その値はフィールドまたはプロパティの型の 既定値 に設定されます。 クラスで少なくとも 1 つのインスタンス コンストラクターを宣言した場合、C# はパラメーターなしのコンストラクターを提供しません。

構造体型は、常にパラメーターなしのコンストラクターを提供します。 パラメーターなしのコンストラクターは、型の既定値を生成する暗黙的なパラメーターなしのコンストラクターか、明示的に宣言されたパラメーターなしのコンストラクターです。 詳細については、「構造体型」の記事の「 構造体の初期化と既定値 」セクションを 参照 してください。

プライマリ コンストラクター

C# 12 以降では、クラスと構造体で プライマリ コンストラクター を宣言できます。 型名の後に、任意のパラメーターをかっこで囲みます。

public class NamedItem(string name)
{
    public string Name => name;
}

プライマリ コンストラクターのパラメーターは、宣言する型の本体全体のスコープ内にあります。 プロパティまたはフィールドを初期化できます。 これらは、メソッドまたはローカル関数の変数として使用できます。 これらは、基本コンストラクターに渡すことができます。

プライマリ コンストラクターは、これらのパラメーターが型の任意のインスタンスに必要であることを示します。 明示的に記述されたコンストラクターは、 this(...) 初期化子構文を使用してプライマリ コンストラクターを呼び出す必要があります。 これにより、プライマリ コンストラクターパラメーターがすべてのコンストラクターによって確実に割り当てられます。 class型を含む任意のrecord class型の場合、プライマリ コンストラクターが存在する場合、暗黙的なパラメーターなしのコンストラクターは出力されません。 struct型を含む任意のrecord struct型の場合、暗黙的なパラメーターなしのコンストラクターは常に出力され、プライマリ コンストラクター パラメーターを含むすべてのフィールドが常に 0 ビット パターンに初期化されます。 明示的なパラメーターなしのコンストラクターを記述する場合は、プライマリ コンストラクターを呼び出す必要があります。 その場合は、プライマリ コンストラクター パラメーターに別の値を指定できます。 次のコードは、プライマリ コンストラクターの例を示しています。

// name isn't captured in Widget.
// width, height, and depth are captured as private fields
public class Widget(string name, int width, int height, int depth) : NamedItem(name)
{
    public Widget() : this("N/A", 1,1,1) {} // unnamed unit cube

    public int WidthInCM => width;
    public int HeightInCM => height;
    public int DepthInCM => depth;

    public int Volume => width * height * depth;
}

合成されたプライマリ コンストラクター メソッドに属性を追加するには、属性に method: ターゲットを指定します。

[method: MyAttribute]
public class TaggedWidget(string name)
{
   // details elided
}

methodターゲットを指定しない場合、属性はメソッドではなくクラスに配置されます。

class型とstruct型では、プライマリ コンストラクター パラメーターは型の本体の任意の場所で使用できます。 このパラメーターは、キャプチャされたプライベート フィールドとして実装できます。 パラメーターへの参照が初期化子とコンストラクター呼び出しのみの場合、そのパラメーターはプライベート フィールドにキャプチャされません。 型の他のメンバーで使用すると、コンパイラはプライベート フィールドでパラメーターをキャプチャします。

型に record 修飾子が含まれている場合、コンパイラは代わりにプライマリ コンストラクター パラメーターと同じ名前のパブリック プロパティを合成します。 record class型の場合、プライマリ コンストラクター パラメーターが基本プライマリ コンストラクターと同じ名前を使用する場合、そのプロパティは基本record class型のパブリック プロパティです。 派生 record class 型では複製されません。 これらのプロパティは、record 以外の型では生成されません。

こちらも参照ください