Delen via


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 gebruiken 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 Apparaat, $dev is dit een object of exemplaar van het type Apparaat. Elk exemplaar van 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 ondervangen door hun typenaam.

Syntax

Definitiesyntaxis

Voor klassedefinities wordt de volgende syntaxis gebruikt:

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

Syntaxis van instantiëring

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 haken geven een typedefinitie voor PowerShell aan.

De hashtable-syntaxis 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, genereert PowerShell een fout.

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 Book-klasse gedefinieerd met verschillende eigenschappen, constructors en methoden. Elk gedefinieerd lid is een exemplaarlid , geen statisch lid. De eigenschappen en methoden zijn alleen toegankelijk 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, gebruikt het voorbeeld de GetReadingTime() methoden en GetPublishedAge() 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 bouwt voort op de klasse Book in voorbeeld 2. Hoewel de klasse BookList zelf niet kan worden gemarkeerd als statisch, 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 van [UnsafeClass] rapporteert verschillende thread-id's, maar dezelfde runspace-id. Uiteindelijk is de sessiestatus beschadigd, waardoor een fout wordt 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

Dit voorbeeld wordt uitgevoerd in een oneindige lus. 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 zijn of een exemplaar van een andere klasse. 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 die invoergegevens opgeven. 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 worden verborgen in de Get-Member cmdlet en kunnen niet worden weergegeven met behulp van tabvoltooiing of IntelliSense buiten de klassedefinitie.

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

Verborgen klasseleden zijn:

  • Niet opgenomen in de standaarduitvoer voor de klasse.
  • Niet opgenomen in de lijst met klasseleden die worden geretourneerd door de Get-Member cmdlet. 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 klasse. Ze kunnen worden geopend, overgenomen en gewijzigd. Als u een lid verbergt, wordt 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, de 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 geen instantie nodig heeft.

Een statische eigenschap is altijd beschikbaar, onafhankelijk van klasse-instantiëring. Een statische eigenschap wordt gedeeld met alle exemplaren van de klasse. Een statische methode is altijd beschikbaar. Alle statische eigenschappen zijn actief gedurende de hele sessieperiode.

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 basisklasseleden indien nodig toevoegen of overschrijven.

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

Klassen kunnen ook overnemen van interfaces, waarmee een contract wordt gedefinieerd. Een klasse die wordt overgenomen 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 implementatieinterfaces.

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 is gemaakt. Het gebruik van een PowerShell-klasse in ForEach-Object -Parallel is niet veilig. Methode-aanroepen op de klasse worden teruggezet naar de Runspace waar deze is gemaakt, wat de status van de Runspace kan beschadigen of een impasse kan veroorzaken.

Zie Voorbeeld 4 voor een illustratie van hoe runspace-affiniteit fouten kan veroorzaken.

Klassen exporteren met typeversnellers

Standaard exporteren PowerShell-modules 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 patroon dat hieronder wordt beschreven, 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 ontvangen, moet u een using module -instructie toevoegen aan het begin van het script.

Het volgende patroon laat zien hoe u PowerShell-klassen en -opsommingen kunt registreren als typeversnellers in een module. Voeg het codefragment toe aan de hoofdscriptmodule na typedefinities. Zorg ervoor dat de $ExportableTypes variabele elk van de typen bevat die u beschikbaar wilt maken voor gebruikers wanneer ze de module importeren. De andere code hoeft niet te worden bewerkt.

# 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 onmiddellijk beschikbaar voor IntelliSense en voltooiing. Wanneer de module wordt verwijderd, geldt dit ook voor de typeversnellers.

Klassen handmatig importeren uit 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 voor deze typen toevoegt, gebruikt u een using module instructie om deze te importeren.

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

Zie about_Using voor meer informatie over deusing -instructie.

Zojuist gewijzigde code laden tijdens de ontwikkeling

Tijdens de ontwikkeling 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. Het is ook niet mogelijk 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 opsplitsen van uw code in verschillende bestanden. Als u een functie in een bestand hebt dat gebruikmaakt van klassen die zijn gedefinieerd in een andere module, moet u de using module instructie gebruiken om ervoor te zorgen dat de functies de klassedefinities hebben die nodig zijn.

Het type PSReference wordt niet ondersteund door klasseleden

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

Zie PSReference Class (PSReference Class) voor meer informatie.

Beperkingen

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

Algemene beperkingen

  • Klasleden kunnen PSReference niet gebruiken als hun type.

    Tijdelijke oplossing: Geen.

  • PowerShell-klassen kunnen niet worden uitgepakt of opnieuw worden 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 worden de typen beschikbaar bij het importeren van modules.

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

    Tijdelijke oplossing: Geen.

  • PowerShell-klassen zijn niet veilig om te gebruiken bij parallelle uitvoering in runspaces. Wanneer u methoden voor een klasse aanroept, worden de aanroepen door PowerShell teruggezet naar de Runspace waar de klasse is gemaakt, wat de status van de runspace kan beschadigen of een impasse kan veroorzaken.

    Tijdelijke 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 constructortekst opnieuw toe met het validatiekenmerk.

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

    Tijdelijke oplossing: Geen.

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

    Tijdelijke oplossing: Geen.

Methodebeperkingen

  • Methodeparameters kunnen geen kenmerken gebruiken, met inbegrip van 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.

  • Met methodeparameters kunnen geen standaardwaarden worden gedefinieerd. De parameters zijn altijd verplicht.

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

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

    Tijdelijke oplossing: Geen.

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

    Tijdelijke oplossing: Geen.

Beperkingen van eigenschappen

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

    Tijdelijke oplossing: Geen.

  • Eigenschappen kunnen het kenmerk ValidateScript niet gebruiken, omdat kenmerkargumenten voor klasse-eigenschappen constanten moeten zijn.

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

  • Met rechtstreeks gedeclareerde eigenschappen kunnen aangepaste getter- en setter-implementaties niet worden gedefinieerd.

    Tijdelijke oplossing: definieer een verborgen eigenschap en gebruik Update-TypeData 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 hun waarden.

    Tijdelijke 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 van één basisklasse overnemen.

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

  • Bij overname van een algemene klasse of interface moet de typeparameter voor het algemene 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