about_Classes_Methods
Korte beschrijving
Hierin wordt beschreven hoe u methoden definieert voor PowerShell-klassen.
Lange beschrijving
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.
In klassemethoden worden er geen objecten verzonden naar de pijplijn, behalve de objecten die zijn opgegeven in de return
instructie. Er is geen onbedoelde uitvoer naar de pijplijn vanuit de code.
Notitie
Dit verschilt van de manier waarop PowerShell-functies uitvoer verwerken, waarbij alles naar de pijplijn gaat.
Niet-bepalende fouten die vanuit een klassemethode naar de foutstroom worden geschreven, worden niet doorgegeven. U moet een throw
afsluitfout weergeven.
Met behulp van de Write-*
cmdlets kunt u nog steeds schrijven naar de uitvoerstromen van PowerShell vanuit een klassemethode. De cmdlets respecteren de voorkeursvariabelen in het aanroepende bereik. U moet echter voorkomen dat u de Write-*
cmdlets gebruikt, zodat de methode alleen objecten uitvoert met behulp van de return
instructie.
Klassemethoden kunnen verwijzen naar het huidige exemplaar van het klasseobject met behulp van de $this
automatische variabele voor toegang tot eigenschappen en andere methoden die zijn gedefinieerd in de huidige klasse. De $this
automatische variabele is niet beschikbaar in statische methoden.
Klassemethoden kunnen een willekeurig aantal kenmerken hebben, waaronder de verborgen en statische kenmerken.
Syntaxis
Klassemethoden gebruiken de volgende syntaxis:
Syntaxis van één regel
[[<attribute>]...] [hidden] [static] [<output-type>] <method-name> ([<method-parameters>]) { <body> }
Syntaxis met meerdere regels
[[<attribute>]...]
[hidden]
[static]
[<output-type>] <method-name> ([<method-parameters>]) {
<body>
}
Voorbeelden
Voorbeeld 1: Definitie van minimale methode
De GetVolume()
methode van de klasse ExampleCube1 retourneert het volume van de kubus. Het definieert het uitvoertype als een zwevend getal en retourneert het resultaat van het vermenigvuldigen van de eigenschappen Height, Length en Width van het exemplaar.
class ExampleCube1 {
[float] $Height
[float] $Length
[float] $Width
[float] GetVolume() { return $this.Height * $this.Length * $this.Width }
}
$box = [ExampleCube1]@{
Height = 2
Length = 2
Width = 3
}
$box.GetVolume()
12
Voorbeeld 2: methode met parameters
De GeWeight()
methode gebruikt een zwevende getalinvoer voor de dichtheid van de kubus en retourneert het gewicht van de kubus, berekend als volume vermenigvuldigd met dichtheid.
class ExampleCube2 {
[float] $Height
[float] $Length
[float] $Width
[float] GetVolume() { return $this.Height * $this.Length * $this.Width }
[float] GetWeight([float]$Density) {
return $this.GetVolume() * $Density
}
}
$cube = [ExampleCube2]@{
Height = 2
Length = 2
Width = 3
}
$cube.GetWeight(2.5)
30
Voorbeeld 3: methode zonder uitvoer
In dit voorbeeld wordt de Validate()
methode gedefinieerd met het uitvoertype System.Void. Deze methode retourneert geen uitvoer. Als de validatie mislukt, treedt er een fout op. De GetVolume()
methode roept aan Validate()
voordat het volume van de kubus wordt berekend. Als de validatie mislukt, wordt de methode beëindigd vóór de berekening.
class ExampleCube3 {
[float] $Height
[float] $Length
[float] $Width
[float] GetVolume() {
$this.Validate()
return $this.Height * $this.Length * $this.Width
}
[void] Validate() {
$InvalidProperties = @()
foreach ($Property in @('Height', 'Length', 'Width')) {
if ($this.$Property -le 0) {
$InvalidProperties += $Property
}
}
if ($InvalidProperties.Count -gt 0) {
$Message = @(
'Invalid cube properties'
"('$($InvalidProperties -join "', '")'):"
"Cube dimensions must all be positive numbers."
) -join ' '
throw $Message
}
}
}
$Cube = [ExampleCube3]@{ Length = 1 ; Width = -1 }
$Cube
$Cube.GetVolume()
Height Length Width
------ ------ -----
0.00 1.00 -1.00
Exception:
Line |
20 | throw $Message
| ~~~~~~~~~~~~~~
| Invalid cube properties ('Height', 'Width'): Cube dimensions must
| all be positive numbers.
De methode genereert een uitzondering omdat de eigenschappen Hoogte en Breedte ongeldig zijn, waardoor de klasse het huidige volume niet kan berekenen.
Voorbeeld 4: statische methode met overbelastingen
De klasse ExampleCube4 definieert de statische methode GetVolume()
met twee overbelastingen. De eerste overbelasting bevat parameters voor de dimensies van de kubus en een vlag om aan te geven of de methode de invoer moet valideren.
De tweede overbelasting bevat alleen de numerieke invoer. Het noemt de eerste overbelasting met $Static
als $true
. De tweede overbelasting biedt gebruikers een manier om de methode aan te roepen zonder altijd te hoeven definiëren of de invoer strikt moet worden gevalideerd.
De klasse definieert GetVolume()
ook als een instantiemethode (niet-statisch). Met deze methode wordt de tweede statische overbelasting aangeroepen, zodat de instantiemethode GetVolume()
altijd de dimensies van de kubus valideert voordat de uitvoerwaarde wordt geretourneerd.
class ExampleCube4 {
[float] $Height
[float] $Length
[float] $Width
static [float] GetVolume(
[float]$Height,
[float]$Length,
[float]$Width,
[boolean]$Strict
) {
$Signature = "[ExampleCube4]::GetVolume({0}, {1}, {2}, {3})"
$Signature = $Signature -f $Height, $Length, $Width, $Strict
Write-Verbose "Called $Signature"
if ($Strict) {
[ValidateScript({$_ -gt 0 })]$Height = $Height
[ValidateScript({$_ -gt 0 })]$Length = $Length
[ValidateScript({$_ -gt 0 })]$Width = $Width
}
return $Height * $Length * $Width
}
static [float] GetVolume([float]$Height, [float]$Length, [float]$Width) {
$Signature = "[ExampleCube4]::GetVolume($Height, $Length, $Width)"
Write-Verbose "Called $Signature"
return [ExampleCube4]::GetVolume($Height, $Length, $Width, $true)
}
[float] GetVolume() {
Write-Verbose "Called `$this.GetVolume()"
return [ExampleCube4]::GetVolume(
$this.Height,
$this.Length,
$this.Width
)
}
}
$VerbosePreference = 'Continue'
$Cube = [ExampleCube4]@{ Height = 2 ; Length = 2 }
$Cube.GetVolume()
VERBOSE: Called $this.GetVolume()
VERBOSE: Called [ExampleCube4]::GetVolume(2, 2, 0)
VERBOSE: Called [ExampleCube4]::GetVolume(2, 2, 0, True)
MetadataError:
Line |
19 | [ValidateScript({$_ -gt 0 })]$Width = $Width
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| The variable cannot be validated because the value 0 is not a valid
| value for the Width variable.
De uitgebreide berichten in de methodedefinities laten zien hoe de initiële aanroep voor het aanroepen van $this.GetVolume()
de statische methode.
Het aanroepen van de statische methode rechtstreeks met de parameter Strict als $false
retourneert 0
voor het volume.
[ExampleCube4]::GetVolume($Cube.Height, $Cube.Length, $Cube.Width, $false)
VERBOSE: Called [ExampleCube4]::GetVolume(2, 2, 0, False)
0
Methodehandtekeningen en overbelastingen
Elke klassemethode heeft een unieke handtekening waarmee wordt gedefinieerd hoe de methode moet worden aangeroepen. Het uitvoertype, de naam en de parameters van de methode definiëren de handtekening van de methode.
Wanneer een klasse meer dan één methode met dezelfde naam definieert, zijn de definities van die methode overbelast. Overbelastingen voor een methode moeten verschillende parameters hebben. Een methode kan geen twee implementaties met dezelfde parameters definiëren, zelfs niet als de uitvoertypen verschillend zijn.
De volgende klasse definieert twee methoden en Shuffle()
Deal()
. De Deal()
methode definieert twee overbelastingen, één zonder parameters en de andere met de parameter Count .
class CardDeck {
[string[]]$Cards = @()
hidden [string[]]$Dealt = @()
hidden [string[]]$Suits = @('Clubs', 'Diamonds', 'Hearts', 'Spades')
hidden [string[]]$Values = 2..10 + @('Jack', 'Queen', 'King', 'Ace')
CardDeck() {
foreach($Suit in $this.Suits) {
foreach($Value in $this.Values) {
$this.Cards += "$Value of $Suit"
}
}
$this.Shuffle()
}
[void] Shuffle() {
$this.Cards = $this.Cards + $this.Dealt | Where-Object -FilterScript {
-not [string]::IsNullOrEmpty($_)
} | Get-Random -Count $this.Cards.Count
}
[string] Deal() {
if ($this.Cards.Count -eq 0) { throw "There are no cards left." }
$Card = $this.Cards[0]
$this.Cards = $this.Cards[1..$this.Cards.Count]
$this.Dealt += $Card
return $Card
}
[string[]] Deal([int]$Count) {
if ($Count -gt $this.Cards.Count) {
throw "There are only $($this.Cards.Count) cards left."
} elseif ($Count -lt 1) {
throw "You must deal at least 1 card."
}
return (1..$Count | ForEach-Object { $this.Deal() })
}
}
Methode-uitvoer
Standaard hebben methoden geen uitvoer. Als een methodehandtekening een ander expliciet uitvoertype dan Void bevat, moet de methode een object van dat type retourneren. Methoden verzenden geen uitvoer, behalve wanneer het return
trefwoord expliciet een object retourneert.
Methodeparameters
Klassemethoden kunnen invoerparameters definiëren die moeten worden gebruikt in de hoofdtekst van de methode. Methodeparameters staan tussen haakjes en worden gescheiden door komma's. Lege haakjes geven aan dat voor de methode geen parameters zijn vereist.
Parameters kunnen worden gedefinieerd op één regel of meerdere regels. In de volgende blokken ziet u de syntaxis voor methodeparameters.
([[<parameter-type>]]$<parameter-name>[, [[<parameter-type>]]$<parameter-name>])
(
[[<parameter-type>]]$<parameter-name>[,
[[<parameter-type>]]$<parameter-name>]
)
Methodeparameters kunnen sterk worden getypt. Als een parameter niet is getypt, accepteert de methode een object voor die parameter. Als de parameter is getypt, probeert de methode de waarde voor die parameter te converteren naar het juiste type, waardoor er een uitzondering wordt gegenereerd als de invoer niet kan worden geconverteerd.
Methodeparameters kunnen geen standaardwaarden definiëren. Alle methodeparameters zijn verplicht.
Methodeparameters kunnen geen andere kenmerken hebben. Hiermee voorkomt u dat methoden parameters met de Validate*
kenmerken gebruiken. Zie about_Functions_Advanced_Parameters voor meer informatie over de validatiekenmerken.
U kunt een van de volgende patronen gebruiken om validatie toe te voegen aan methodeparameters:
- Wijs de parameters opnieuw toe aan dezelfde variabelen met de vereiste validatiekenmerken. Dit werkt voor zowel statische als instantiemethoden. Zie voorbeeld 4 voor een voorbeeld van dit patroon.
- Gebruik
Update-TypeData
dit om eenScriptMethod
te definiëren die rechtstreeks gebruikmaakt van validatiekenmerken op de parameters. Dit werkt alleen voor exemplaarmethoden. Zie de sectie Exemplaarmethoden definiëren met de sectie Update-TypeData voor meer informatie.
Automatische variabelen in methoden
Niet alle automatische variabelen zijn beschikbaar in methoden. De volgende lijst bevat automatische variabelen en suggesties voor het gebruik ervan in PowerShell-klassenmethoden. Automatische variabelen die niet in de lijst zijn opgenomen, zijn niet beschikbaar voor klassemethoden.
$?
- Toegang als normaal.$_
- Toegang als normaal.$args
- Gebruik in plaats daarvan de expliciete parametervariabelen.$ConsoleFileName
- Toegang zoals$Script:ConsoleFileName
in plaats daarvan.$Error
- Toegang als normaal.$EnabledExperimentalFeatures
- Toegang zoals$Script:EnabledExperimentalFeatures
in plaats daarvan.$Event
- Toegang als normaal.$EventArgs
- Toegang als normaal.$EventSubscriber
- Toegang als normaal.$ExecutionContext
- Toegang zoals$Script:ExecutionContext
in plaats daarvan.$false
- Toegang als normaal.$foreach
- Toegang als normaal.$HOME
- Toegang zoals$Script:HOME
in plaats daarvan.$Host
- Toegang zoals$Script:Host
in plaats daarvan.$input
- Gebruik in plaats daarvan de expliciete parametervariabelen.$IsCoreCLR
- Toegang zoals$Script:IsCoreCLR
in plaats daarvan.$IsLinux
- Toegang zoals$Script:IsLinux
in plaats daarvan.$IsMacOS
- Toegang zoals$Script:IsMacOS
in plaats daarvan.$IsWindows
- Toegang zoals$Script:IsWindows
in plaats daarvan.$LASTEXITCODE
- Toegang als normaal.$Matches
- Toegang als normaal.$MyInvocation
- Toegang als normaal.$NestedPromptLevel
- Toegang als normaal.$null
- Toegang als normaal.$PID
- Toegang zoals$Script:PID
in plaats daarvan.$PROFILE
- Toegang zoals$Script:PROFILE
in plaats daarvan.$PSBoundParameters
- Gebruik deze variabele niet. Deze is bedoeld voor cmdlets en functies. Het gebruik ervan in een klas kan onverwachte bijwerkingen hebben.$PSCmdlet
- Gebruik deze variabele niet. Deze is bedoeld voor cmdlets en functies. Het gebruik ervan in een klas kan onverwachte bijwerkingen hebben.$PSCommandPath
- Toegang als normaal.$PSCulture
- Toegang zoals$Script:PSCulture
in plaats daarvan.$PSEdition
- Toegang zoals$Script:PSEdition
in plaats daarvan.$PSHOME
- Toegang zoals$Script:PSHOME
in plaats daarvan.$PSItem
- Toegang als normaal.$PSScriptRoot
- Toegang als normaal.$PSSenderInfo
- Toegang zoals$Script:PSSenderInfo
in plaats daarvan.$PSUICulture
- Toegang zoals$Script:PSUICulture
in plaats daarvan.$PSVersionTable
- Toegang zoals$Script:PSVersionTable
in plaats daarvan.$PWD
- Toegang als normaal.$Sender
- Toegang als normaal.$ShellId
- Toegang zoals$Script:ShellId
in plaats daarvan.$StackTrace
- Toegang als normaal.$switch
- Toegang als normaal.$this
- Toegang als normaal. In een klassemethode$this
is altijd het huidige exemplaar van de klasse. U kunt hiermee toegang krijgen tot de klasse-eigenschappen en -methoden. Het is niet beschikbaar in statische methoden.$true
- Toegang als normaal.
Zie about_Automatic_Variables voor meer informatie over automatische variabelen.
Verborgen methoden
U kunt methoden van een klasse verbergen door ze te declareren met het hidden
trefwoord.
Verborgen klassemethoden zijn:
- Niet opgenomen in de lijst met klasseleden die door de
Get-Member
cmdlet worden geretourneerd. Als u verborgen methoden wilt weergeven,Get-Member
gebruikt u de parameter Force . - Niet weergegeven in tabvoltooiing of IntelliSense, tenzij de voltooiing plaatsvindt in de klasse die de verborgen methode definieert.
- Openbare leden van de klas. Ze kunnen worden aangeroepen en overgenomen. Het verbergen van een methode maakt het niet privé. De methode 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
.
Zie about_Hidden voor meer informatie over het hidden
trefwoord.
Statische methoden
U kunt een methode definiëren als behorend tot de klasse zelf in plaats van exemplaren van de klasse door de methode met het static
trefwoord te declareren. Statische klassemethoden:
- Zijn altijd beschikbaar, onafhankelijk van klasse-instantiëring.
- Worden gedeeld in alle exemplaren van de klasse.
- Zijn altijd beschikbaar.
- Kan geen toegang krijgen tot exemplaareigenschappen van de klasse. Ze hebben alleen toegang tot statische eigenschappen.
- Live voor het hele sessiebereik.
Afgeleide klassemethoden
Wanneer een klasse is afgeleid van een basisklasse, neemt deze de methoden van de basisklasse en hun overbelasting over. Eventuele overbelasting van methoden die zijn gedefinieerd op de basisklasse, inclusief verborgen methoden, zijn beschikbaar in de afgeleide klasse.
Een afgeleide klasse kan de overbelasting van een overgenomen methode overschrijven door deze opnieuw te definiëren in de klassedefinitie. Als u de overbelasting wilt overschrijven, moeten de parametertypen hetzelfde zijn als voor de basisklasse. Het uitvoertype voor de overbelasting kan verschillen.
In tegenstelling tot constructors kunnen methoden de : base(<parameters>)
syntaxis niet gebruiken om een overbelasting van de basisklasse voor de methode aan te roepen. De opnieuw gedefinieerde overbelasting van de afgeleide klasse vervangt de overbelasting die door de basisklasse is gedefinieerd.
In het volgende voorbeeld ziet u het gedrag voor statische en exemplaarmethoden voor afgeleide klassen.
De basisklasse definieert:
- De statische methoden
Now()
voor het retourneren van de huidige tijd enDaysAgo()
voor het retourneren van een datum in het verleden. - De instantieeigenschap TimeStamp en een
ToString()
instantiemethode die de tekenreeksweergave van die eigenschap retourneert. Dit zorgt ervoor dat wanneer een exemplaar wordt gebruikt in een tekenreeks die wordt geconverteerd naar de datum/tijd-tekenreeks in plaats van de klassenaam. - De instantiemethode
SetTimeStamp()
met twee overbelastingen. Wanneer de methode zonder parameters wordt aangeroepen, wordt de TimeStamp ingesteld op de huidige tijd. Wanneer de methode wordt aangeroepen met een Datum/tijd, wordt de TimeStamp ingesteld op die waarde.
class BaseClass {
static [datetime] Now() {
return Get-Date
}
static [datetime] DaysAgo([int]$Count) {
return [BaseClass]::Now().AddDays(-$Count)
}
[datetime] $TimeStamp = [BaseClass]::Now()
[string] ToString() {
return $this.TimeStamp.ToString()
}
[void] SetTimeStamp([datetime]$TimeStamp) {
$this.TimeStamp = $TimeStamp
}
[void] SetTimeStamp() {
$this.TimeStamp = [BaseClass]::Now()
}
}
In het volgende blok worden klassen gedefinieerd die zijn afgeleid van BaseClass:
- DerivedClassA neemt over van BaseClass zonder overschrijvingen.
- DerivedClassB overschrijft de
DaysAgo()
statische methode om een tekenreeksweergave te retourneren in plaats van het DateTime-object . De instantiemethode wordt ook overschrevenToString()
om de tijdstempel als een ISO8601 datumtekenreeks te retourneren. - DerivedClassC overschrijft de parameterloze overbelasting van de
SetTimeStamp()
methode, zodat het instellen van de tijdstempel zonder parameters de datum instelt op 10 dagen vóór de huidige datum.
class DerivedClassA : BaseClass {}
class DerivedClassB : BaseClass {
static [string] DaysAgo([int]$Count) {
return [BaseClass]::DaysAgo($Count).ToString('yyyy-MM-dd')
}
[string] ToString() {
return $this.TimeStamp.ToString('yyyy-MM-dd')
}
}
class DerivedClassC : BaseClass {
[void] SetTimeStamp() {
$this.SetTimeStamp([BaseClass]::Now().AddDays(-10))
}
}
In het volgende blok ziet u de uitvoer van de statische Now()
methode voor de gedefinieerde klassen. De uitvoer is voor elke klasse hetzelfde, omdat de afgeleide klassen de implementatie van de basisklasse van de methode niet overschrijven.
"[BaseClass]::Now() => $([BaseClass]::Now())"
"[DerivedClassA]::Now() => $([DerivedClassA]::Now())"
"[DerivedClassB]::Now() => $([DerivedClassB]::Now())"
"[DerivedClassC]::Now() => $([DerivedClassC]::Now())"
[BaseClass]::Now() => 11/06/2023 09:41:23
[DerivedClassA]::Now() => 11/06/2023 09:41:23
[DerivedClassB]::Now() => 11/06/2023 09:41:23
[DerivedClassC]::Now() => 11/06/2023 09:41:23
In het volgende blok wordt de DaysAgo()
statische methode van elke klasse aangeroepen. Alleen de uitvoer voor DerivedClassB is anders, omdat deze de basis-implementatie overroest.
"[BaseClass]::DaysAgo(3) => $([BaseClass]::DaysAgo(3))"
"[DerivedClassA]::DaysAgo(3) => $([DerivedClassA]::DaysAgo(3))"
"[DerivedClassB]::DaysAgo(3) => $([DerivedClassB]::DaysAgo(3))"
"[DerivedClassC]::DaysAgo(3) => $([DerivedClassC]::DaysAgo(3))"
[BaseClass]::DaysAgo(3) => 11/03/2023 09:41:38
[DerivedClassA]::DaysAgo(3) => 11/03/2023 09:41:38
[DerivedClassB]::DaysAgo(3) => 2023-11-03
[DerivedClassC]::DaysAgo(3) => 11/03/2023 09:41:38
In het volgende blok ziet u de tekenreekspresentatie van een nieuw exemplaar voor elke klasse. De weergave voor DerivedClassB is anders omdat deze de ToString()
instantiemethode overroest.
"`$base = [BaseClass]::New() => $($base = [BaseClass]::New(); $base)"
"`$a = [DerivedClassA]::New() => $($a = [DerivedClassA]::New(); $a)"
"`$b = [DerivedClassB]::New() => $($b = [DerivedClassB]::New(); $b)"
"`$c = [DerivedClassC]::New() => $($c = [DerivedClassC]::New(); $c)"
$base = [BaseClass]::New() => 11/6/2023 9:44:57 AM
$a = [DerivedClassA]::New() => 11/6/2023 9:44:57 AM
$b = [DerivedClassB]::New() => 2023-11-06
$c = [DerivedClassC]::New() => 11/6/2023 9:44:57 AM
In het volgende blok wordt de SetTimeStamp()
instantiemethode voor elk exemplaar aangeroepen, waarbij de eigenschap TimeStamp wordt ingesteld op een specifieke datum. Elk exemplaar heeft dezelfde datum, omdat geen van de afgeleide klassen de geparameteriseerde overbelasting voor de methode overschrijft.
[datetime]$Stamp = '2024-10-31'
"`$base.SetTimeStamp(`$Stamp) => $($base.SetTimeStamp($Stamp) ; $base)"
"`$a.SetTimeStamp(`$Stamp) => $($a.SetTimeStamp($Stamp); $a)"
"`$b.SetTimeStamp(`$Stamp) => $($b.SetTimeStamp($Stamp); $b)"
"`$c.SetTimeStamp(`$Stamp) => $($c.SetTimeStamp($Stamp); $c)"
$base.SetTimeStamp($Stamp) => 10/31/2024 12:00:00 AM
$a.SetTimeStamp($Stamp) => 10/31/2024 12:00:00 AM
$b.SetTimeStamp($Stamp) => 2024-10-31
$c.SetTimeStamp($Stamp) => 10/31/2024 12:00:00 AM
De laatste blokoproepen SetTimeStamp()
zonder parameters. De uitvoer laat zien dat de waarde voor het AfgeleideClassC-exemplaar is ingesteld op 10 dagen voor de andere exemplaren.
"`$base.SetTimeStamp() => $($base.SetTimeStamp() ; $base)"
"`$a.SetTimeStamp() => $($a.SetTimeStamp(); $a)"
"`$b.SetTimeStamp() => $($b.SetTimeStamp(); $b)"
"`$c.SetTimeStamp() => $($c.SetTimeStamp(); $c)"
$base.SetTimeStamp() => 11/6/2023 9:53:58 AM
$a.SetTimeStamp() => 11/6/2023 9:53:58 AM
$b.SetTimeStamp() => 2023-11-06
$c.SetTimeStamp() => 10/27/2023 9:53:58 AM
Exemplaarmethoden definiëren met Update-TypeData
Naast het rechtstreeks declareren van methoden in de klassedefinitie, kunt u methoden 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 <ClassName> {
static [hashtable[]] $MemberDefinitions = @(
@{
MemberName = '<MethodName>'
MemberType = 'ScriptMethod'
Value = {
param(<method-parameters>)
<method-body>
}
}
)
static <ClassName>() {
$TypeName = [<ClassName>].Name
foreach ($Definition in [<ClassName>]::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.
Methoden definiëren met standaardparameterwaarden en validatiekenmerken
Methoden die rechtstreeks in een klassedeclaratie zijn gedefinieerd, kunnen geen standaardwaarden of validatiekenmerken definiëren voor de methodeparameters. Als u klassemethoden met standaardwaarden of validatiekenmerken wilt definiëren, moeten ze worden gedefinieerd als ScriptMethod-leden .
In dit voorbeeld definieert de klasse CardDeck een Draw()
methode die gebruikmaakt van zowel een validatiekenmerk als een standaardwaarde voor de parameter Count .
class CookieJar {
[int] $Cookies = 12
static [hashtable[]] $MemberDefinitions = @(
@{
MemberName = 'Eat'
MemberType = 'ScriptMethod'
Value = {
param(
[ValidateScript({ $_ -ge 1 -and $_ -le $this.Cookies })]
[int] $Count = 1
)
$this.Cookies -= $Count
if ($Count -eq 1) {
"You ate 1 cookie. There are $($this.Cookies) left."
} else {
"You ate $Count cookies. There are $($this.Cookies) left."
}
}
}
)
static CookieJar() {
$TypeName = [CookieJar].Name
foreach ($Definition in [CookieJar]::MemberDefinitions) {
Update-TypeData -TypeName $TypeName @Definition
}
}
}
$Jar = [CookieJar]::new()
$Jar.Eat(1)
$Jar.Eat()
$Jar.Eat(20)
$Jar.Eat(6)
You ate 1 cookie. There are 11 left.
You ate 1 cookie. There are 10 left.
MethodInvocationException:
Line |
36 | $Jar.Eat(20)
| ~~~~~~~~~~~~
| Exception calling "Eat" with "1" argument(s): "The attribute
| cannot be added because variable Count with value 20 would no
| longer be valid."
You ate 6 cookies. There are 4 left.
Notitie
Hoewel dit patroon geschikt is voor validatiekenmerken, ziet u dat de uitzondering misleidend is en verwijst naar een onvermogen om een kenmerk toe te voegen. Het kan een betere gebruikerservaring zijn om expliciet de waarde voor de parameter te controleren en in plaats daarvan een zinvolle fout te genereren. Op die manier kunnen gebruikers begrijpen waarom ze de fout zien en wat ze eraan moeten doen.
Beperkingen
PowerShell-klassemethoden hebben de volgende beperkingen:
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.