about_Classes

Korte beschrijving

Hierin wordt beschreven hoe u klassen kunt gebruiken om uw eigen aangepaste typen te maken.

Lange beschrijving

Vanaf versie 5.0 heeft PowerShell een formele syntaxis voor het definiëren van klassen en andere door de gebruiker gedefinieerde typen. Dankzij de toevoeging van klassen kunnen ontwikkelaars en IT-professionals PowerShell omarmen voor een breder scala aan gebruiksvoorbeelden.

Een klassedeclaratie is een blauwdruk die wordt gebruikt voor het maken van exemplaren van objecten tijdens runtime. Wanneer u een klasse definieert, is de klassenaam de naam van het type. Als u bijvoorbeeld een klasse met de naam Apparaat declareert en een variabele $dev initialiseert naar een nieuw exemplaar van Het apparaat, $dev is dit een object of exemplaar van het type Apparaat. Elk exemplaar van Het apparaat kan verschillende waarden in de eigenschappen hebben.

Ondersteunde scenario's

  • Definieer aangepaste typen in PowerShell met behulp van objectgeoriënteerde programmeersemantiek, zoals klassen, eigenschappen, methoden, overname, enzovoort.
  • Definieer DSC-resources en de bijbehorende typen met behulp van de PowerShell-taal.
  • Definieer aangepaste kenmerken om variabelen, parameters en aangepaste typedefinities te versieren.
  • Definieer aangepaste uitzonderingen die kunnen worden opgevangen door hun typenaam.

Syntaxis

Definitiesyntaxis

Klassedefinities gebruiken de volgende syntaxis:

class <class-name> [: [<base-class>][,<interface-list>]] {
    [[<attribute>] [hidden] [static] <property-definition> ...]
    [<class-name>([<constructor-argument-list>])
      {<constructor-statement-list>} ...]
    [[<attribute>] [hidden] [static] <method-definition> ...]
}

Instantiatiesyntaxis

Als u een instantie van een klasse wilt instantiëren, gebruikt u een van de volgende syntaxis:

[$<variable-name> =] New-Object -TypeName <class-name> [
  [-ArgumentList] <constructor-argument-list>]
[$<variable-name> =] [<class-name>]::new([<constructor-argument-list>])
[$<variable-name> =] [<class-name>]@{[<class-property-hashtable>]}

Notitie

Wanneer u de [<class-name>]::new() syntaxis gebruikt, zijn vierkante haken rond de klassenaam verplicht. De haakjes geven een typedefinitie voor PowerShell aan.

De hashtabelsyntaxis werkt alleen voor klassen met een standaardconstructor die geen parameters verwacht. Er wordt een exemplaar van de klasse gemaakt met de standaardconstructor en vervolgens worden de sleutel-waardeparen toegewezen aan de exemplaareigenschappen. Als een sleutel in de hashtabel geen geldige eigenschapsnaam is, wordt er een fout gegenereerd in PowerShell.

Voorbeelden

Voorbeeld 1: minimale definitie

In dit voorbeeld ziet u de minimale syntaxis die nodig is om een bruikbare klasse te maken.

class Device {
    [string]$Brand
}

$dev = [Device]::new()
$dev.Brand = "Fabrikam, Inc."
$dev
Brand
-----
Fabrikam, Inc.

Voorbeeld 2: Klasse met exemplaarleden

In dit voorbeeld wordt een bookklasse gedefinieerd met verschillende eigenschappen, constructors en methoden. Elk gedefinieerd lid is een exemplaarlid , geen statisch lid. De eigenschappen en methoden kunnen alleen worden geopend via een gemaakt exemplaar van de klasse.

class Book {
    # Class properties
    [string]   $Title
    [string]   $Author
    [string]   $Synopsis
    [string]   $Publisher
    [datetime] $PublishDate
    [int]      $PageCount
    [string[]] $Tags
    # Default constructor
    Book() { $this.Init(@{}) }
    # Convenience constructor from hashtable
    Book([hashtable]$Properties) { $this.Init($Properties) }
    # Common constructor for title and author
    Book([string]$Title, [string]$Author) {
        $this.Init(@{Title = $Title; Author = $Author })
    }
    # Shared initializer method
    [void] Init([hashtable]$Properties) {
        foreach ($Property in $Properties.Keys) {
            $this.$Property = $Properties.$Property
        }
    }
    # Method to calculate reading time as 2 minutes per page
    [timespan] GetReadingTime() {
        if ($this.PageCount -le 0) {
            throw 'Unable to determine reading time from page count.'
        }
        $Minutes = $this.PageCount * 2
        return [timespan]::new(0, $Minutes, 0)
    }
    # Method to calculate how long ago a book was published
    [timespan] GetPublishedAge() {
        if (
            $null -eq $this.PublishDate -or
            $this.PublishDate -eq [datetime]::MinValue
        ) { throw 'PublishDate not defined' }

        return (Get-Date) - $this.PublishDate
    }
    # Method to return a string representation of the book
    [string] ToString() {
        return "$($this.Title) by $($this.Author) ($($this.PublishDate.Year))"
    }
}

Het volgende codefragment maakt een exemplaar van de klasse en laat zien hoe deze zich gedraagt. Nadat u een exemplaar van de klasse Book hebt gemaakt, worden in het voorbeeld de GetReadingTime() en GetPublishedAge() methoden gebruikt om een bericht over het boek te schrijven.

$Book = [Book]::new(@{
    Title       = 'The Hobbit'
    Author      = 'J.R.R. Tolkien'
    Publisher   = 'George Allen & Unwin'
    PublishDate = '1937-09-21'
    PageCount   = 310
    Tags        = @('Fantasy', 'Adventure')
})

$Book
$Time = $Book.GetReadingTime()
$Time = @($Time.Hours, 'hours and', $Time.Minutes, 'minutes') -join ' '
$Age  = [Math]::Floor($Book.GetPublishedAge().TotalDays / 365.25)

"It takes $Time to read $Book,`nwhich was published $Age years ago."
Title       : The Hobbit
Author      : J.R.R. Tolkien
Synopsis    :
Publisher   : George Allen & Unwin
PublishDate : 9/21/1937 12:00:00 AM
PageCount   : 310
Tags        : {Fantasy, Adventure}

It takes 10 hours and 20 minutes to read The Hobbit by J.R.R. Tolkien (1937),
which was published 86 years ago.

Voorbeeld 3: Klasse met statische leden

De klasse BookList in dit voorbeeld is gebaseerd op de klasse Boek in voorbeeld 2. Hoewel de klasse BookList niet kan worden gemarkeerd als statisch zelf, definieert de implementatie alleen de statische eigenschap Books en een set statische methoden voor het beheren van die eigenschap.

class BookList {
    # Static property to hold the list of books
    static [System.Collections.Generic.List[Book]] $Books
    # Static method to initialize the list of books. Called in the other
    # static methods to avoid needing to explicit initialize the value.
    static [void] Initialize()             { [BookList]::Initialize($false) }
    static [bool] Initialize([bool]$force) {
        if ([BookList]::Books.Count -gt 0 -and -not $force) {
            return $false
        }

        [BookList]::Books = [System.Collections.Generic.List[Book]]::new()

        return $true
    }
    # Ensure a book is valid for the list.
    static [void] Validate([book]$Book) {
        $Prefix = @(
            'Book validation failed: Book must be defined with the Title,'
            'Author, and PublishDate properties, but'
        ) -join ' '
        if ($null -eq $Book) { throw "$Prefix was null" }
        if ([string]::IsNullOrEmpty($Book.Title)) {
            throw "$Prefix Title wasn't defined"
        }
        if ([string]::IsNullOrEmpty($Book.Author)) {
            throw "$Prefix Author wasn't defined"
        }
        if ([datetime]::MinValue -eq $Book.PublishDate) {
            throw "$Prefix PublishDate wasn't defined"
        }
    }
    # Static methods to manage the list of books.
    # Add a book if it's not already in the list.
    static [void] Add([Book]$Book) {
        [BookList]::Initialize()
        [BookList]::Validate($Book)
        if ([BookList]::Books.Contains($Book)) {
            throw "Book '$Book' already in list"
        }

        $FindPredicate = {
            param([Book]$b)

            $b.Title -eq $Book.Title -and
            $b.Author -eq $Book.Author -and
            $b.PublishDate -eq $Book.PublishDate
        }.GetNewClosure()
        if ([BookList]::Books.Find($FindPredicate)) {
            throw "Book '$Book' already in list"
        }

        [BookList]::Books.Add($Book)
    }
    # Clear the list of books.
    static [void] Clear() {
      [BookList]::Initialize()
      [BookList]::Books.Clear()
    }
    # Find a specific book using a filtering scriptblock.
    static [Book] Find([scriptblock]$Predicate) {
        [BookList]::Initialize()
        return [BookList]::Books.Find($Predicate)
    }
    # Find every book matching the filtering scriptblock.
    static [Book[]] FindAll([scriptblock]$Predicate) {
        [BookList]::Initialize()
        return [BookList]::Books.FindAll($Predicate)
    }
    # Remove a specific book.
    static [void] Remove([Book]$Book) {
        [BookList]::Initialize()
        [BookList]::Books.Remove($Book)
    }
    # Remove a book by property value.
    static [void] RemoveBy([string]$Property, [string]$Value) {
        [BookList]::Initialize()
        $Index = [BookList]::Books.FindIndex({
            param($b)
            $b.$Property -eq $Value
        }.GetNewClosure())
        if ($Index -ge 0) {
            [BookList]::Books.RemoveAt($Index)
        }
    }
}

Nu BookList is gedefinieerd, kan het boek uit het vorige voorbeeld worden toegevoegd aan de lijst.

$null -eq [BookList]::Books

[BookList]::Add($Book)

[BookList]::Books
True

Title       : The Hobbit
Author      : J.R.R. Tolkien
Synopsis    :
Publisher   : George Allen & Unwin
PublishDate : 9/21/1937 12:00:00 AM
PageCount   : 310
Tags        : {Fantasy, Adventure}

In het volgende codefragment worden de statische methoden voor de klasse aangeroepen.

[BookList]::Add([Book]::new(@{
    Title       = 'The Fellowship of the Ring'
    Author      = 'J.R.R. Tolkien'
    Publisher   = 'George Allen & Unwin'
    PublishDate = '1954-07-29'
    PageCount   = 423
    Tags        = @('Fantasy', 'Adventure')
}))

[BookList]::Find({
    param ($b)

    $b.PublishDate -gt '1950-01-01'
}).Title

[BookList]::FindAll({
    param($b)

    $b.Author -match 'Tolkien'
}).Title

[BookList]::Remove($Book)
[BookList]::Books.Title

[BookList]::RemoveBy('Author', 'J.R.R. Tolkien')
"Titles: $([BookList]::Books.Title)"

[BookList]::Add($Book)
[BookList]::Add($Book)
The Fellowship of the Ring

The Hobbit
The Fellowship of the Ring

The Fellowship of the Ring

Titles:

Exception:
Line |
  84 |              throw "Book '$Book' already in list"
     |              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Book 'The Hobbit by J.R.R. Tolkien (1937)' already in list

Voorbeeld 4: parallelle uitvoering die een runspace beschadigd

De ShowRunspaceId() methode voor het melden van [UnsafeClass] verschillende thread-id's, maar dezelfde runspace-id. Uiteindelijk is de sessiestatus beschadigd die een fout veroorzaakt, zoals Global scope cannot be removed.

# Class definition with Runspace affinity (default behavior)
class UnsafeClass {
    static [object] ShowRunspaceId($val) {
        return [PSCustomObject]@{
            ThreadId   = [Threading.Thread]::CurrentThread.ManagedThreadId
            RunspaceId = [runspace]::DefaultRunspace.Id
        }
    }
}

$unsafe = [UnsafeClass]::new()

while ($true) {
    1..10 | ForEach-Object -Parallel {
        Start-Sleep -ms 100
        ($using:unsafe)::ShowRunspaceId($_)
    }
}

Notitie

In dit voorbeeld wordt een oneindige lus uitgevoerd. Voer Ctrl+C in om de uitvoering te stoppen.

Klasse-eigenschappen

Eigenschappen zijn variabelen die zijn gedeclareerd in het klassebereik. Een eigenschap kan van elk ingebouwd type of een exemplaar van een andere klasse zijn. Klassen kunnen nul of meer eigenschappen hebben. Klassen hebben geen maximumaantal eigenschappen.

Zie about_Classes_Properties voor meer informatie.

Klassemethoden

Methoden definiëren de acties die een klasse kan uitvoeren. Methoden kunnen parameters gebruiken waarmee invoergegevens worden opgegeven. Methoden definiëren altijd een uitvoertype. Als een methode geen uitvoer retourneert, moet deze het uitvoertype Void hebben. Als een methode niet expliciet een uitvoertype definieert, is het uitvoertype van de methode Void.

Zie about_Classes_Methods voor meer informatie.

Klasseconstructors

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.

Zie about_Classes_Constructors voor meer informatie.

Verborgen trefwoord

Het hidden trefwoord verbergt een klasselid. Het lid is nog steeds toegankelijk voor de gebruiker en is beschikbaar in alle bereiken waarin het object beschikbaar is. Verborgen leden zijn verborgen voor de Get-Member cmdlet en kunnen niet worden weergegeven met tabvoltooiing of IntelliSense buiten de klassedefinitie.

Het hidden trefwoord is alleen van toepassing op klasseleden, niet op een klasse zelf.

Verborgen klasleden 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 leden wilt weergeven met Get-Member, gebruikt u de parameter Force .
  • Niet weergegeven in tabvoltooiing of IntelliSense, tenzij de voltooiing plaatsvindt in de klasse die het verborgen lid definieert.
  • Openbare leden van de klas. Ze kunnen worden geopend, overgenomen en gewijzigd. Het verbergen van een lid maakt het niet privé. Het lid wordt alleen verborgen zoals beschreven in de vorige punten.

Notitie

Wanneer u een overbelasting voor een methode verbergt, wordt die methode verwijderd uit IntelliSense, voltooiingsresultaten en de standaarduitvoer voor Get-Member. Wanneer u een constructor verbergt, wordt de new() optie verwijderd uit IntelliSense en voltooiingsresultaten.

Zie about_Hidden voor meer informatie over het trefwoord. Zie about_Classes_Properties voor meer informatie over verborgen eigenschappen. Zie about_Classes_Methods voor meer informatie over verborgen methoden. Zie about_Classes_Constructors voor meer informatie over verborgen constructors.

Statisch trefwoord

Het static trefwoord definieert een eigenschap of een methode die bestaat in de klasse en heeft geen exemplaar nodig.

Een statische eigenschap is altijd beschikbaar, onafhankelijk van klasse-instantiëring. Een statische eigenschap wordt gedeeld in alle exemplaren van de klasse. Er is altijd een statische methode beschikbaar. Alle statische eigenschappen zijn live voor het hele sessiebereik.

Het static trefwoord is alleen van toepassing op klasseleden, niet op een klasse zelf.

Zie about_Classes_Properties voor meer informatie over statische eigenschappen. Zie about_Classes_Methods voor meer informatie over statische methoden. Zie about_Classes_Constructors voor meer informatie over statische constructors.

Overname in PowerShell-klassen

U kunt een klasse uitbreiden door een nieuwe klasse te maken die is afgeleid van een bestaande klasse. De afgeleide klasse neemt de eigenschappen en methoden van de basisklasse over. U kunt de leden van de basisklasse toevoegen of overschrijven zoals vereist.

PowerShell biedt geen ondersteuning voor meerdere overnames. Klassen kunnen niet rechtstreeks overnemen van meer dan één klasse.

Klassen kunnen ook overnemen van interfaces, waarmee een contract wordt gedefinieerd. Een klasse die overkomt van een interface, moet dat contract implementeren. Wanneer dit het geval is, kan de klasse worden gebruikt zoals elke andere klasse die die interface implementeert.

Zie about_Classes_Inheritance voor meer informatie over het afleiden van klassen die overnemen van een basisklasse of het implementeren van interfaces.

Runspace-affiniteit

Een runspace is de besturingsomgeving voor de opdrachten die worden aangeroepen door PowerShell. Deze omgeving bevat de opdrachten en gegevens die momenteel aanwezig zijn en eventuele taalbeperkingen die momenteel van toepassing zijn.

Een PowerShell-klasse is gekoppeld aan de Runspace waar deze wordt gemaakt. Het gebruik van een PowerShell-klasse in ForEach-Object -Parallel is niet veilig. Methode-aanroepen van de klasse worden teruggezet naar de Runspace waar deze is gemaakt, waardoor de status van de Runspace kan worden beschadigd of een impasse ontstaat.

Zie voorbeeld 4 voor een afbeelding van hoe runspaceaffiniteit fouten kan veroorzaken.

Klassen exporteren met typeversnellers

PowerShell-modules exporteren standaard niet automatisch klassen en opsommingen die zijn gedefinieerd in PowerShell. De aangepaste typen zijn niet beschikbaar buiten de module zonder een using module instructie aan te roepen.

Als een module echter typeversnellers toevoegt, zijn deze typeversnellers onmiddellijk beschikbaar in de sessie nadat gebruikers de module hebben geïmporteerd.

Notitie

Het toevoegen van typeversnellers aan de sessie maakt gebruik van een interne (niet openbare) API. Het gebruik van deze API kan conflicten veroorzaken. Het onderstaande patroon genereert een fout als er al een typeversneller met dezelfde naam bestaat wanneer u de module importeert. Ook worden de typeversnellers verwijderd wanneer u de module uit de sessie verwijdert.

Dit patroon zorgt ervoor dat de typen beschikbaar zijn in een sessie. Dit heeft geen invloed op IntelliSense of voltooiing bij het ontwerpen van een scriptbestand in VS Code. Als u IntelliSense en voltooiingssuggesties voor aangepaste typen in VS Code wilt ophalen, moet u een using module instructie toevoegen aan het begin van het script.

In het volgende patroon ziet u hoe u PowerShell-klassen en -opsommingen kunt registreren als typeversnellers in een module. Voeg het fragment toe aan de hoofdscriptmodule na een typedefinitie. Zorg ervoor dat de $ExportableTypes variabele elk van de typen bevat die u beschikbaar wilt maken voor gebruikers wanneer ze de module importeren. Voor de andere code is geen bewerking vereist.

# Define the types to export with type accelerators.
$ExportableTypes =@(
    [DefinedTypeName]
)
# Get the internal TypeAccelerators class to use its static methods.
$TypeAcceleratorsClass = [psobject].Assembly.GetType(
    'System.Management.Automation.TypeAccelerators'
)
# Ensure none of the types would clobber an existing type accelerator.
# If a type accelerator with the same name exists, throw an exception.
$ExistingTypeAccelerators = $TypeAcceleratorsClass::Get
foreach ($Type in $ExportableTypes) {
    if ($Type.FullName -in $ExistingTypeAccelerators.Keys) {
        $Message = @(
            "Unable to register type accelerator '$($Type.FullName)'"
            'Accelerator already exists.'
        ) -join ' - '

        throw [System.Management.Automation.ErrorRecord]::new(
            [System.InvalidOperationException]::new($Message),
            'TypeAcceleratorAlreadyExists',
            [System.Management.Automation.ErrorCategory]::InvalidOperation,
            $Type.FullName
        )
    }
}
# Add type accelerators for every exportable type.
foreach ($Type in $ExportableTypes) {
    $TypeAcceleratorsClass::Add($Type.FullName, $Type)
}
# Remove type accelerators when the module is removed.
$MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = {
    foreach($Type in $ExportableTypes) {
        $TypeAcceleratorsClass::Remove($Type.FullName)
    }
}.GetNewClosure()

Wanneer gebruikers de module importeren, zijn alle typen die zijn toegevoegd aan de typeversnellers voor de sessie direct beschikbaar voor IntelliSense en voltooiing. Wanneer de module wordt verwijderd, zijn dit de typeversnellers.

Klassen handmatig importeren vanuit een PowerShell-module

Import-Module en de #requires instructie importeert alleen de modulefuncties, aliassen en variabelen, zoals gedefinieerd door de module. Klassen worden niet geïmporteerd.

Als een module klassen en opsommingen definieert, maar geen typeversnellers toevoegt voor deze typen, gebruikt u een using module instructie om ze te importeren.

Met using module de instructie worden klassen en opsommingen geïmporteerd uit de hoofdmodule (ModuleToProcess) van een scriptmodule of binaire module. Klassen die zijn gedefinieerd in geneste modules of klassen die zijn gedefinieerd in scripts die zijn gedefinieerd in de hoofdmodule, worden niet consistent geïmporteerd. Definieer klassen die u rechtstreeks in de hoofdmodule beschikbaar wilt maken voor gebruikers buiten de module.

Zie about_Using voor meer informatie over de using instructie.

Nieuw gewijzigde code laden tijdens de ontwikkeling

Tijdens het ontwikkelen van een scriptmodule is het gebruikelijk om wijzigingen aan te brengen in de code en vervolgens de nieuwe versie van de module te laden met behulp van Import-Module de parameter Force . Het opnieuw laden van de module werkt alleen voor wijzigingen in functies in de hoofdmodule. Import-Module laadt geen geneste modules opnieuw. Er is ook geen manier om bijgewerkte klassen te laden.

Om ervoor te zorgen dat u de nieuwste versie uitvoert, moet u een nieuwe sessie starten. Klassen en opsommingen die zijn gedefinieerd in PowerShell en geïmporteerd met een using instructie, kunnen niet worden uitgepakt.

Een andere gangbare ontwikkelpraktijk is het scheiden van uw code in verschillende bestanden. Als u een functie hebt in een bestand dat klassen gebruikt die zijn gedefinieerd in een andere module, moet u de using module instructie gebruiken om ervoor te zorgen dat de functies over de klassendefinities beschikken die nodig zijn.

Het type PSReference wordt niet ondersteund met klasseleden

De [ref] typeversneller is afkorting voor de PSReference-klasse . Het gebruik [ref] om een klasselid te typen, mislukt op de achtergrond. API's die gebruikmaken van [ref] parameters kunnen niet worden gebruikt met klasseleden. De PSReference-klasse is ontworpen ter ondersteuning van COM-objecten. COM-objecten hebben gevallen waarin u een waarde per verwijzing moet doorgeven.

Zie PSReference Class voor meer informatie.

Beperkingen

De volgende lijsten bevatten beperkingen voor het definiëren van PowerShell-klassen en tijdelijke oplossingen voor deze beperkingen, indien van toepassing.

Algemene beperkingen

  • Klasleden kunnen PSReference niet gebruiken als hun type.

    Oplossing: Geen.

  • PowerShell-klassen kunnen niet worden uitgepakt of opnieuw geladen in een sessie.

    Tijdelijke oplossing: start een nieuwe sessie.

  • PowerShell-klassen die in een module zijn gedefinieerd, worden niet automatisch geïmporteerd.

    Tijdelijke oplossing: Voeg de gedefinieerde typen toe aan de lijst met typeversnellers in de hoofdmodule. Hierdoor zijn de typen beschikbaar voor het importeren van modules.

  • De hidden en static trefwoorden zijn alleen van toepassing op klasseleden, niet op een klassedefinitie.

    Oplossing: Geen.

  • PowerShell-klassen zijn niet veilig voor parallelle uitvoering in runspaces. Wanneer u methoden voor een klasse aanroept, marshallt PowerShell de aanroepen terug naar de Runspace waar de klasse is gemaakt, wat de status van de Runspace kan beschadigen of een impasse kan veroorzaken.

    Oplossing: Geen.

Constructorbeperkingen

  • 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.

Methodebeperkingen

  • Methodeparameters kunnen geen kenmerken gebruiken, inclusief validatiekenmerken.

    Tijdelijke oplossing: wijs de parameters in de hoofdtekst van de methode opnieuw toe met het validatiekenmerk of definieer de methode in de statische constructor met de Update-TypeData cmdlet.

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

    Tijdelijke oplossing: Definieer de methode in de statische constructor met de Update-TypeData cmdlet.

  • Methoden zijn altijd openbaar, zelfs als ze verborgen zijn. Ze kunnen worden overschreven wanneer de klasse wordt overgenomen.

    Oplossing: Geen.

  • Als een overbelasting van een methode verborgen is, wordt elke overbelasting voor die methode ook als verborgen behandeld.

    Oplossing: Geen.

Beperkingen van eigenschappen

  • Statische eigenschappen zijn altijd veranderlijk. PowerShell-klassen kunnen geen onveranderbare statische eigenschappen definiëren.

    Oplossing: Geen.

  • Eigenschappen kunnen het kenmerk ValidateScript niet gebruiken, omdat argumenten van het kenmerk klasse-eigenschap constanten moeten zijn.

    Tijdelijke oplossing: Definieer een klasse die wordt overgenomen van het type ValidateArgumentsAttribute en gebruik dat kenmerk in plaats daarvan.

  • Rechtstreeks gedeclareerde eigenschappen kunnen geen aangepaste getter- en setter-implementaties definiëren.

    Tijdelijke oplossing: definieer een verborgen eigenschap en gebruik Update-TypeData deze om de zichtbare getter- en setterlogica te definiëren.

  • Eigenschappen kunnen het aliaskenmerk niet gebruiken. Het kenmerk is alleen van toepassing op parameters, cmdlets en functies.

    Tijdelijke oplossing: gebruik de Update-TypeData cmdlet om aliassen in de klasseconstructors te definiëren.

  • Wanneer een PowerShell-klasse wordt geconverteerd naar JSON met de ConvertTo-Json cmdlet, bevat de uitvoer-JSON alle verborgen eigenschappen en de bijbehorende waarden.

    Oplossing: Geen

Overnamebeperkingen

  • PowerShell biedt geen ondersteuning voor het definiëren van interfaces in scriptcode.

    Tijdelijke oplossing: Definieer interfaces in C# en verwijs naar de assembly die de interfaces definieert.

  • PowerShell-klassen kunnen slechts één basisklasse overnemen.

    Tijdelijke oplossing: overname van klassen is transitief. Een afgeleide klasse kan overnemen van een andere afgeleide klasse om de eigenschappen en methoden van een basisklasse op te halen.

  • Bij het overnemen van een algemene klasse of interface moet de typeparameter voor de algemene klasse al zijn gedefinieerd. Een klasse kan zichzelf niet definiëren als de typeparameter voor een klasse of interface.

    Tijdelijke oplossing: Als u wilt afleiden van een algemene basisklasse of interface, definieert u het aangepaste type in een ander .psm1 bestand en gebruikt u de using module instructie om het type te laden. Er is geen tijdelijke oplossing voor een aangepast type om zichzelf te gebruiken als de typeparameter bij het overnemen van een algemeen type.

Zie ook