Delen via


about_Classes_Constructors

Korte beschrijving

Hierin wordt beschreven hoe u constructors definieert voor PowerShell-klassen.

Lange beschrijving

Met constructors kunt u standaardwaarden instellen en objectlogica valideren op het moment dat het exemplaar van de klasse wordt gemaakt. Constructors hebben dezelfde naam als de klasse. Constructors kunnen parameters hebben om de gegevensleden van het nieuwe object te initialiseren.

PowerShell-klasseconstructors worden gedefinieerd als speciale methoden in de klasse. Ze gedragen zich hetzelfde als PowerShell-klassemethoden met de volgende uitzonderingen:

  • Constructors hebben geen uitvoertype. Ze kunnen het return trefwoord niet gebruiken.
  • Constructors hebben altijd dezelfde naam als de klasse.
  • Constructors kunnen niet rechtstreeks worden aangeroepen. Ze worden alleen uitgevoerd wanneer een exemplaar wordt gemaakt.
  • Constructors worden nooit weergegeven in de uitvoer voor de Get-Member cmdlet.

Zie about_Classes_Methods voor meer informatie over PowerShell-klassemethoden.

De klasse kan nul of meer constructors hebben gedefinieerd. Als er geen constructor is gedefinieerd, krijgt de klasse een standaardconstructor zonder parameters. Met deze constructor worden alle leden geïnitialiseerd naar hun standaardwaarden. Objecttypen en tekenreeksen krijgen null-waarden. Wanneer u een constructor definieert, wordt er geen standaardparameterloze constructor gemaakt. Maak indien nodig een parameterloze constructor.

U kunt ook een statische constructor zonder parameters definiëren.

Syntaxis

Klasseconstructors gebruiken de volgende syntaxis:

Standaardconstructorsyntaxis

<class-name> () [: base([<params>])] {
    <body>
}

Syntaxis van statische constructor

static <class-name> () [: base([<params>])] {
    <body>
}

Geparameteriseerde constructorsyntaxis (één regel)

<class-name> ([[<parameter-type>]$<parameter-name>[, [<parameter-type>]$<parameter-name>...]]) [: base([<params>])] {
    <body>
}

Geparameteriseerde constructorsyntaxis (meerdere regels)

<class-name> (
    [<parameter-type>]$<parameter-name>[,
    [<parameter-type>]$<parameter-name>...]
) [: base([<params>])] {
    <body>
}

Voorbeelden

Voorbeeld 1: Een klasse definiëren met de standaardconstructor

De klasse ExampleBook1 definieert geen constructor. In plaats daarvan wordt de automatische standaardconstructor gebruikt.

class ExampleBook1 {
    [string]   $Name
    [string]   $Author
    [int]      $Pages
    [datetime] $PublishedOn
}

[ExampleBook1]::new()
Name Author Pages PublishedOn
---- ------ ----- -----------
                0 1/1/0001 12:00:00 AM

Notitie

De standaardwaarde voor de eigenschappen Naam en Auteur is $null omdat deze als tekenreeksen worden getypt. Dit is een verwijzingstype. De andere eigenschappen hebben de standaardwaarde voor het gedefinieerde type, omdat het eigenschappen van het waardetype zijn. Zie 'Standaardeigenschapswaarden' in about_Classes_Properties voor meer informatie over de standaardwaarden voor eigenschappen.

Voorbeeld 2: de standaardconstructor overschrijven

ExampleBook2 definieert expliciet de standaardconstructor, waarbij de waarden voor PublishedOn worden ingesteld op de huidige datum en pagina's1.

class ExampleBook2 {
    [string]   $Name
    [string]   $Author
    [int]      $Pages
    [datetime] $PublishedOn

    ExampleBook2() {
        $this.PublishedOn = (Get-Date).Date
        $this.Pages       = 1
    }
}

[ExampleBook2]::new()
Name Author Pages PublishedOn
---- ------ ----- -----------
                1 11/1/2023 12:00:00 AM

Voorbeeld 3: constructoroverbelastingen definiëren

De klasse ExampleBook3 definieert drie constructoroverbelastingen, zodat gebruikers een exemplaar van de klasse kunnen maken op basis van een hashtabel, door elke eigenschapswaarde door te geven en door de naam van het boek en de auteur door te geven. De klasse definieert niet de standaardconstructor.

class ExampleBook3 {
    [string]   $Name
    [string]   $Author
    [int]      $Pages
    [datetime] $PublishedOn

    ExampleBook3([hashtable]$Info) {
        switch ($Info.Keys) {
            'Name'        { $this.Name        = $Info.Name }
            'Author'      { $this.Author      = $Info.Author }
            'Pages'       { $this.Pages       = $Info.Pages }
            'PublishedOn' { $this.PublishedOn = $Info.PublishedOn }
        }
    }

    ExampleBook3(
        [string]   $Name,
        [string]   $Author,
        [int]      $Pages,
        [datetime] $PublishedOn
    ) {
        $this.Name        = $Name
        $this.Author      = $Author
        $this.Pages       = $Pages
        $this.PublishedOn = $PublishedOn
    }

    ExampleBook3([string]$Name, [string]$Author) {
        $this.Name   = $Name
        $this.Author = $Author
    }
}

[ExampleBook3]::new(@{
    Name        = 'The Hobbit'
    Author      = 'J.R.R. Tolkien'
    Pages       = 310
    PublishedOn = '1937-09-21'
})
[ExampleBook3]::new('The Hobbit', 'J.R.R. Tolkien', 310, '1937-09-21')
[ExampleBook3]::new('The Hobbit', 'J.R.R. Tolkien')
[ExampleBook3]::new()
Name       Author         Pages PublishedOn
----       ------         ----- -----------
The Hobbit J.R.R. Tolkien   310 9/21/1937 12:00:00 AM
The Hobbit J.R.R. Tolkien   310 9/21/1937 12:00:00 AM
The Hobbit J.R.R. Tolkien     0 1/1/0001 12:00:00 AM

MethodException:
Line |
  42 |  [ExampleBook3]::new()
     |  ~~~~~~~~~~~~~~~~~~~~~
     | Cannot find an overload for "new" and the argument count: "0".

Als u de standaardconstructor aanroept, wordt een methode-uitzondering geretourneerd. De automatische standaardconstructor wordt alleen gedefinieerd voor een klasse wanneer de klasse geen constructors definieert. Omdat ExampleBook3 meerdere overbelastingen definieert, wordt de standaardconstructor niet automatisch toegevoegd aan de klasse.

Voorbeeld 4: constructors koppelen met een gedeelde methode

In dit voorbeeld ziet u hoe u herbruikbare gedeelde code kunt schrijven voor constructors. PowerShell-klassen kunnen geen constructorkoppeling gebruiken, dus in deze voorbeeldklasse wordt een methode gedefinieerd Init() . De methode heeft verschillende overbelastingen. De overbelastingen met minder parameters roepen de meer expliciete overbelastingen aan met standaardwaarden voor de niet-opgegeven parameters.

class ExampleBook4 {
    [string]   $Name
    [string]   $Author
    [datetime] $PublishedOn
    [int]      $Pages

    ExampleBook4() {
        $this.Init()
    }
    ExampleBook4([string]$Name) {
        $this.Init($Name)
    }
    ExampleBook4([string]$Name, [string]$Author) {
        $this.Init($Name, $Author)
    }
    ExampleBook4([string]$Name, [string]$Author, [datetime]$PublishedOn) {
        $this.Init($Name, $Author, $PublishedOn)
    }
    ExampleBook4(
      [string]$Name,
      [string]$Author,
      [datetime]$PublishedOn,
      [int]$Pages
    ) {
        $this.Init($Name, $Author, $PublishedOn, $Pages)
    }

    hidden Init() {
        $this.Init('Unknown')
    }
    hidden Init([string]$Name) {
        $this.Init($Name, 'Unknown')
    }
    hidden Init([string]$Name, [string]$Author) {
        $this.Init($Name, $Author, (Get-Date).Date)
    }
    hidden Init([string]$Name, [string]$Author, [datetime]$PublishedOn) {
        $this.Init($Name, $Author, $PublishedOn, 1)
    }
    hidden Init(
        [string]$Name,
        [string]$Author,
        [datetime]$PublishedOn,
        [int]$Pages
      ) {
        $this.Name        = $Name
        $this.Author      = $Author
        $this.PublishedOn = $PublishedOn
        $this.Pages       = $Pages
    }
}

[ExampleBook4]::new()
[ExampleBook4]::new('The Hobbit')
[ExampleBook4]::new('The Hobbit', 'J.R.R. Tolkien')
[ExampleBook4]::new('The Hobbit', 'J.R.R. Tolkien', (Get-Date '1937-9-21'))
[ExampleBook4]::new(
    'The Hobbit',
    'J.R.R. Tolkien',
    (Get-Date '1937-9-21'),
    310
)
Name       Author         PublishedOn           Pages
----       ------         -----------           -----
Unknown    Unknown        11/1/2023 12:00:00 AM     1
The Hobbit Unknown        11/1/2023 12:00:00 AM     1
The Hobbit J.R.R. Tolkien 11/1/2023 12:00:00 AM     1
The Hobbit J.R.R. Tolkien 9/21/1937 12:00:00 AM     1
The Hobbit J.R.R. Tolkien 9/21/1937 12:00:00 AM   310

Voorbeeld 5- Afgeleide klasseconstructors

In de volgende voorbeelden worden klassen gebruikt die de statische, standaard- en geparameteriseerde constructors definiëren voor een basisklasse en een afgeleide klasse die wordt overgenomen van de basisklasse.

class BaseExample {
    static [void] DefaultMessage([type]$Type) {
        Write-Verbose "[$($Type.Name)] default constructor"
    }

    static [void] StaticMessage([type]$Type) {
        Write-Verbose "[$($Type.Name)] static constructor"
    }

    static [void] ParamMessage([type]$Type, [object]$Value) {
        Write-Verbose "[$($Type.Name)] param constructor ($Value)"
    }

    static BaseExample() { [BaseExample]::StaticMessage([BaseExample])  }
    BaseExample()        { [BaseExample]::DefaultMessage([BaseExample]) }
    BaseExample($Value)  { [BaseExample]::ParamMessage([BaseExample], $Value) }
}

class DerivedExample : BaseExample {
    static DerivedExample() { [BaseExample]::StaticMessage([DerivedExample])  }
           DerivedExample() { [BaseExample]::DefaultMessage([DerivedExample]) }

    DerivedExample([int]$Number) : base($Number) {
        [BaseExample]::ParamMessage([DerivedExample], $Number)
    }
    DerivedExample([string]$String) {
        [BaseExample]::ParamMessage([DerivedExample], $String)
    }
}

In het volgende blok ziet u de uitgebreide berichten voor het aanroepen van de basisklasseconstructors. Het statische constructorbericht wordt alleen verzonden wanneer er voor het eerst een exemplaar van de klasse wordt gemaakt.

PS> $VerbosePreference = 'Continue'
PS> $b = [BaseExample]::new()

VERBOSE: [BaseExample] static constructor
VERBOSE: [BaseExample] default constructor

PS> $b = [BaseExample]::new()

VERBOSE: [BaseExample] default constructor

PS> $b = [BaseExample]::new(1)

VERBOSE: [BaseExample] param constructor (1)

In het volgende blok ziet u de uitgebreide berichten voor het aanroepen van de afgeleide klasseconstructors in een nieuwe sessie. De eerste keer dat een afgeleide klasseconstructor wordt aangeroepen, worden de statische constructors voor de basisklasse en afgeleide klasse aangeroepen. Deze constructors worden niet opnieuw aangeroepen in de sessie. De constructors voor de basisklasse worden altijd uitgevoerd vóór de constructors voor de afgeleide klasse.

PS> $VerbosePreference = 'Continue'
PS> $c = [DerivedExample]::new()

VERBOSE: [BaseExample] static constructor
VERBOSE: [DerivedExample] static constructor
VERBOSE: [BaseExample] default constructor
VERBOSE: [DerivedExample] default constructor

PS> $c = [DerivedExample]::new()

VERBOSE: [BaseExample] default constructor
VERBOSE: [DerivedExample] default constructor

PS> $c = [DerivedExample]::new(1)

VERBOSE: [BaseExample] param constructor (1)
VERBOSE: [DerivedExample] param constructor (1)

PS> $c = [DerivedExample]::new('foo')

VERBOSE: [BaseExample] default constructor
VERBOSE: [DerivedExample] param constructor (foo)

Volgorde van uitvoering van constructor

Wanneer een klasse wordt geïnstitueerd, wordt de code voor een of meer constructors uitgevoerd.

Voor klassen die niet overnemen van een andere klasse, is de volgorde:

  1. De statische constructor voor de klasse.
  2. De betreffende constructor-overbelasting voor de klasse.

Voor afgeleide klassen die overnemen van een andere klasse, is de volgorde:

  1. De statische constructor voor de basisklasse.
  2. De statische constructor voor de afgeleide klasse.
  3. Als de afgeleide klasseconstructor expliciet een overbelasting van een basisconstructor aanroept, wordt die constructor voor de basisklasse uitgevoerd. Als er geen basisconstructor wordt aangeroepen, wordt de standaardconstructor voor de basisklasse uitgevoerd.
  4. De toepasselijke constructor-overbelasting voor de afgeleide klasse.

In alle gevallen worden statische constructors slechts één keer uitgevoerd in een sessie.

Zie voorbeeld 5 voor een voorbeeld van constructorgedrag en -volgorde.

Verborgen constructors

U kunt constructors van een klasse verbergen door ze te declareren met het hidden trefwoord. Verborgen klasseconstructors zijn:

  • Niet opgenomen in de standaarduitvoer voor de klasse.
  • Niet opgenomen in de lijst met klasseleden die door de Get-Member cmdlet worden geretourneerd. Als u verborgen eigenschappen wilt weergeven met Get-Member, gebruikt u de parameter Force .
  • Niet weergegeven in tabvoltooiing of IntelliSense, tenzij de voltooiing plaatsvindt in de klasse die de verborgen eigenschap definieert.
  • Openbare leden van de klas. Ze kunnen worden geopend en gewijzigd. Het verbergen van een eigenschap maakt het niet privé. De eigenschap wordt alleen verborgen zoals beschreven in de vorige punten.

Notitie

Wanneer u een constructor verbergt, wordt de new() optie verwijderd uit IntelliSense en voltooiingsresultaten.

Zie about_Hidden voor meer informatie over het hidden trefwoord.

Statische constructors

U kunt een constructor definiëren als behorend tot de klasse zelf in plaats van exemplaren van de klasse door de constructor met het static trefwoord te declareren. Statische klasseconstructors:

  • Roep alleen de eerste keer aan dat een exemplaar van de klasse wordt gemaakt in de sessie.
  • Kan geen parameters hebben.
  • Kan geen toegang krijgen tot exemplaareigenschappen of -methoden met de $this variabele.

Constructors voor afgeleide klassen

Wanneer een klasse wordt overgenomen van een andere klasse, kunnen constructors een constructor aanroepen vanuit de basisklasse met het base trefwoord. Als de afgeleide klasse niet expliciet een constructor aanroept van de basisklasse, wordt in plaats daarvan de standaardconstructor voor de basisklasse aangeroepen.

Als u een niet-standaardbasisconstructor wilt aanroepen, voegt u deze toe : base(<parameters>) na de constructorparameters en vóór het hoofdtekstblok.

class <derived-class> : <base-class> {
    <derived-class>(<derived-parameters>) : <base-class>(<base-parameters>) {
        # initialization code
    }
}

Bij het definiëren van een constructor die een basisklasseconstructor aanroept, kunnen de parameters een van de volgende items zijn:

  • De variabele van een parameter voor de afgeleide klasseconstructor.
  • Elke statische waarde.
  • Elke expressie die resulteert in een waarde van het parametertype.

Zie voorbeeld 5 voor een voorbeeld van constructors in een afgeleide klasse.

Ketenconstructors

In tegenstelling tot C# kunnen PowerShell-klasseconstructors geen gebruik maken van ketens met de : this(<parameters>) syntaxis. Als u codeduplicatie wilt verminderen, gebruikt u een verborgen Init() methode met meerdere overbelastingen tot hetzelfde effect. In voorbeeld 4 ziet u een klasse met dit patroon.

Exemplaareigenschappen en -methoden toevoegen met Update-TypeData

Naast het rechtstreeks declareren van eigenschappen en methoden in de klassedefinitie, kunt u eigenschappen definiëren voor exemplaren van een klasse in de statische constructor met behulp van de Update-TypeData cmdlet.

Gebruik dit fragment als uitgangspunt voor het patroon. Vervang indien nodig de tekst van de tijdelijke aanduiding tussen punthaken.

class <class-name> {
    static [hashtable[]] $MemberDefinitions = @(
        @{
            Name       = '<member-name>'
            MemberType = '<member-type>'
            Value      = <member-definition>
        }
    )

    static <class-name>() {
        $TypeName = [<class-name>].Name
        foreach ($Definition in [<class-name>]::MemberDefinitions) {
            Update-TypeData -TypeName $TypeName @Definition
        }
    }
}

Tip

De Add-Member cmdlet kan eigenschappen en methoden toevoegen aan een klasse in niet-statische constructors, maar de cmdlet wordt elke keer uitgevoerd wanneer de constructor wordt aangeroepen. Het gebruik Update-TypeData in de statische constructor zorgt ervoor dat de code voor het toevoegen van de leden aan de klasse slechts eenmaal in een sessie hoeft te worden uitgevoerd.

Voeg alleen eigenschappen toe aan de klasse in niet-statische constructors wanneer ze niet kunnen worden gedefinieerd met Update-TypeData, zoals alleen-lezeneigenschappen.

Zie about_Classes_Methods voor meer informatie over het definiëren van exemplaarmethoden.Update-TypeData Zie about_Classes_Properties voor meer informatie over het definiëren van exemplaareigenschappen.Update-TypeData

Beperkingen

PowerShell-klasseconstructors hebben de volgende beperkingen:

  • Constructorkoppeling is niet geïmplementeerd.

    Tijdelijke oplossing: Definieer verborgen Init() methoden en roep deze aan vanuit de constructors.

  • Constructorparameters kunnen geen kenmerken gebruiken, inclusief validatiekenmerken.

    Tijdelijke oplossing: wijs de parameters in de hoofdtekst van de constructor opnieuw toe met het validatiekenmerk.

  • Constructorparameters kunnen geen standaardwaarden definiëren. De parameters zijn altijd verplicht.

    Oplossing: Geen.

  • Als een overbelasting van een constructor verborgen is, wordt elke overbelasting voor de constructor ook als verborgen behandeld.

    Oplossing: Geen.

Zie ook