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: Klassedefinitie met en zonder Runspace-affiniteit
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.
De ShowRunspaceId()
methode van [SafeClass]
rapporten verschillende thread- en Runspace-id's.
# Class definition with NoRunspaceAffinity attribute
[NoRunspaceAffinity()]
class SafeClass {
static [object] ShowRunspaceId($val) {
return [PSCustomObject]@{
ThreadId = [Threading.Thread]::CurrentThread.ManagedThreadId
RunspaceId = [runspace]::DefaultRunspace.Id
}
}
}
$safe = [SafeClass]::new()
while ($true) {
1..10 | ForEach-Object -Parallel {
Start-Sleep -ms 100
($using:safe)::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 metGet-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.
Kenmerk NoRunspaceAffinity
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.
Standaard is een PowerShell-klasse 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.
Als u het NoRunspaceAffinity
kenmerk toevoegt aan de klassedefinitie, zorgt u ervoor dat de PowerShell-klasse niet is gekoppeld aan een bepaalde runspace. Methode-aanroepen, zowel instantie als statisch, gebruiken de Runspace van de actieve thread en de huidige sessiestatus van de thread.
Het kenmerk is toegevoegd in PowerShell 7.4.
Zie voorbeeld 4 voor een afbeelding van het verschil in gedrag voor klassen met en zonder het NoRunspaceAffinity
kenmerk.
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
enstatic
trefwoorden zijn alleen van toepassing op klasseleden, niet op een klassedefinitie.Oplossing: Geen.
PowerShell-klassen zijn standaard 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.
Tijdelijke oplossing: voeg het
NoRunspaceAffinity
kenmerk toe aan de klassedeclaratie.
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 deusing 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.