Share via


Exemplaarconstructors (C#-programmeerhandleiding)

U declareert een instantieconstructor om de code op te geven die wordt uitgevoerd wanneer u een nieuw exemplaar van een type met de new expressie maakt. Als u een statische klasse of statische variabelen in een niet-statische klasse wilt initialiseren, kunt u een statische constructor definiëren.

Zoals in het volgende voorbeeld wordt weergegeven, kunt u verschillende exemplaarconstructors in één type declareren:

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

In het voorgaande voorbeeld roept de eerste, parameterloze constructor de tweede constructor aan met beide argumenten gelijk 0. Gebruik hiervoor het this trefwoord.

Wanneer u een instantieconstructor declareert in een afgeleide klasse, kunt u een constructor van een basisklasse aanroepen. Gebruik hiervoor het base trefwoord, zoals in het volgende voorbeeld wordt weergegeven:

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

Parameterloze constructors

Als een klasse geen expliciete exemplaarconstructors heeft, biedt C# een parameterloze constructor die u kunt gebruiken om een exemplaar van die klasse te instantiëren, zoals in het volgende voorbeeld wordt weergegeven:

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

Deze constructor initialiseert instantievelden en -eigenschappen volgens de bijbehorende initialisaties. Als een veld of eigenschap geen initialisatiefunctie heeft, wordt de waarde ervan ingesteld op de standaardwaarde van het type veld of eigenschap. Als u ten minste één exemplaarconstructor in een klasse declareert, biedt C# geen parameterloze constructor.

Een structuurtype biedt altijd een parameterloze constructor. De parameterloze constructor is een impliciete parameterloze constructor die de standaardwaarde van een type produceert of een expliciet gedeclareerde parameterloze constructor. Zie de sectie Struct initialisatie en standaardwaarden van het artikel Structuurtypen voor meer informatie.

Primaire constructors

Vanaf C# 12 kunt u een primaire constructor declareren in klassen en structs. U plaatst parameters tussen haakjes na de typenaam:

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

De parameters voor een primaire constructor vallen binnen het bereik in de hele hoofdtekst van het declaratietype. Ze kunnen eigenschappen of velden initialiseren. Ze kunnen worden gebruikt als variabelen in methoden of lokale functies. Ze kunnen worden doorgegeven aan een basisconstructor.

Een primaire constructor geeft aan dat deze parameters nodig zijn voor elk exemplaar van het type. Elke expliciet geschreven constructor moet de syntaxis van de this(...) initialisatiefunctie gebruiken om de primaire constructor aan te roepen. Dit zorgt ervoor dat de primaire constructorparameters zeker door alle constructors worden toegewezen. Voor elk class type, inclusief record class typen, wordt de impliciete parameterloze constructor niet verzonden wanneer een primaire constructor aanwezig is. Voor elk struct type, inclusief record struct typen, wordt de impliciete parameterloze constructor altijd verzonden en worden alle velden, inclusief primaire constructorparameters, altijd geïnitialiseerd naar het 0-bits patroon. Als u een expliciete parameterloze constructor schrijft, moet deze de primaire constructor aanroepen. In dat geval kunt u een andere waarde opgeven voor de primaire constructorparameters. De volgende code toont voorbeelden van primaire constructors.

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

U kunt kenmerken toevoegen aan de gesynthetiseerde primaire constructormethode door het method: doel op te geven op het kenmerk:

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

Als u het method doel niet opgeeft, wordt het kenmerk in de klasse geplaatst in plaats van de methode.

In class en struct typen zijn primaire constructorparameters overal in de hoofdtekst van het type beschikbaar. Ze kunnen worden gebruikt als lidvelden. Wanneer een primaire constructorparameter wordt gebruikt, legt de compiler de constructorparameter vast in een privéveld met een door compiler gegenereerde naam. Als er geen primaire constructorparameter wordt gebruikt in de hoofdtekst van het type, wordt er geen privéveld vastgelegd. Deze regel voorkomt dat per ongeluk twee kopieën van een primaire constructorparameter worden toewijzen die wordt doorgegeven aan een basisconstructor.

Als het type de record wijzigingsfunctie bevat, maakt de compiler in plaats daarvan een openbare eigenschap samen met dezelfde naam als de primaire constructorparameter. Als record class voor typen een primaire constructorparameter dezelfde naam als een primaire basisconstructor gebruikt, is die eigenschap een openbare eigenschap van het basistype record class . Het wordt niet gedupliceerd in het afgeleide record class type. Deze eigenschappen worden niet gegenereerd voor niet-typenrecord .

Zie ook