about_Classes_Constructors
Kort beskrivning
Beskriver hur du definierar konstruktorer för PowerShell-klasser.
Lång beskrivning
Med konstruktorer kan du ange standardvärden och validera objektlogik när du skapar -instansen av klassen. Konstruktorer har samma namn som klassen. Konstruktorer kan ha parametrar för att initiera datamedlemmarna i det nya objektet.
PowerShell-klasskonstruktorer definieras som särskilda metoder för klassen. De beter sig på samma sätt som PowerShell-klassmetoder med följande undantag:
- Konstruktorer har ingen utdatatyp. De kan inte använda nyckelordet
return
. - Konstruktorer har alltid samma namn som klassen.
- Konstruktorer kan inte anropas direkt. De körs bara när en instans skapas.
- Konstruktorer visas aldrig i utdata för cmdleten
Get-Member
.
Mer information om PowerShell-klassmetoder finns i about_Classes_Methods.
Klassen kan ha noll eller fler konstruktorer definierade. Om ingen konstruktor har definierats får klassen en standardkonstruktor utan parameter. Den här konstruktorn initierar alla medlemmar till deras standardvärden. Objekttyper och strängar får null-värden. När du definierar konstruktorn skapas ingen standardparameterlös konstruktor. Skapa en parameterlös konstruktor om det behövs.
Du kan också definiera en statisk konstruktor utan parametrar.
Syntax
Klasskonstruktorer använder följande syntaxer:
Standardkonstruktorsyntax
<class-name> () [: base([<params>])] {
<body>
}
Syntax för statisk konstruktor
static <class-name> () [: base([<params>])] {
<body>
}
Parameteriserad konstruktorsyntax (enrad)
<class-name> ([[<parameter-type>]$<parameter-name>[, [<parameter-type>]$<parameter-name>...]]) [: base([<params>])] {
<body>
}
Parameteriserad konstruktorsyntax (flera ledningar)
<class-name> (
[<parameter-type>]$<parameter-name>[,
[<parameter-type>]$<parameter-name>...]
) [: base([<params>])] {
<body>
}
Exempel
Exempel 1 – Definiera en klass med standardkonstruktorn
Klassen ExampleBook1 definierar inte någon konstruktor. I stället används den automatiska standardkonstruktorn.
class ExampleBook1 {
[string] $Name
[string] $Author
[int] $Pages
[datetime] $PublishedOn
}
[ExampleBook1]::new()
Name Author Pages PublishedOn
---- ------ ----- -----------
0 1/1/0001 12:00:00 AM
Kommentar
Standardvärdet för egenskaperna Namn och Författare beror $null
på att de skrivs som strängar, vilket är en referenstyp. De andra egenskaperna har standardvärdet för sin definierade typ, eftersom de är värdetypsegenskaper. Mer information om standardvärdena för egenskaper finns i "Standardegenskapsvärden" i about_Classes_Properties.
Exempel 2 – Åsidosätta standardkonstruktorn
ExampleBook2 definierar uttryckligen standardkonstruktorn och anger värdena för PublishedOn till aktuellt datum och Sidor till 1
.
class ExampleBook2 {
[string] $Name
[string] $Author
[int] $Pages
[datetime] $PublishedOn
ExampleBook2() {
$this.PublishedOn = (Get-Date).Date
$this.Pages = 1
}
}
[ExampleBook2]::new()
Name Author Pages PublishedOn
---- ------ ----- -----------
1 11/1/2023 12:00:00 AM
Exempel 3 – Definiera konstruktoröverlagringar
Klassen ExampleBook3 definierar tre konstruktoröverlagringar, vilket gör det möjligt för användare att skapa en instans av klassen från en hashtable, genom att skicka varje egenskapsvärde och genom att skicka namnet på boken och författaren. Klassen definierar inte standardkonstruktorn.
class ExampleBook3 {
[string] $Name
[string] $Author
[int] $Pages
[datetime] $PublishedOn
ExampleBook3([hashtable]$Info) {
switch ($Info.Keys) {
'Name' { $this.Name = $Info.Name }
'Author' { $this.Author = $Info.Author }
'Pages' { $this.Pages = $Info.Pages }
'PublishedOn' { $this.PublishedOn = $Info.PublishedOn }
}
}
ExampleBook3(
[string] $Name,
[string] $Author,
[int] $Pages,
[datetime] $PublishedOn
) {
$this.Name = $Name
$this.Author = $Author
$this.Pages = $Pages
$this.PublishedOn = $PublishedOn
}
ExampleBook3([string]$Name, [string]$Author) {
$this.Name = $Name
$this.Author = $Author
}
}
[ExampleBook3]::new(@{
Name = 'The Hobbit'
Author = 'J.R.R. Tolkien'
Pages = 310
PublishedOn = '1937-09-21'
})
[ExampleBook3]::new('The Hobbit', 'J.R.R. Tolkien', 310, '1937-09-21')
[ExampleBook3]::new('The Hobbit', 'J.R.R. Tolkien')
[ExampleBook3]::new()
Name Author Pages PublishedOn
---- ------ ----- -----------
The Hobbit J.R.R. Tolkien 310 9/21/1937 12:00:00 AM
The Hobbit J.R.R. Tolkien 310 9/21/1937 12:00:00 AM
The Hobbit J.R.R. Tolkien 0 1/1/0001 12:00:00 AM
MethodException:
Line |
42 | [ExampleBook3]::new()
| ~~~~~~~~~~~~~~~~~~~~~
| Cannot find an overload for "new" and the argument count: "0".
Om du anropar standardkonstruktorn returneras ett metodfel. Den automatiska standardkonstruktorn definieras bara för en klass när klassen inte definierar några konstruktorer. Eftersom ExampleBook3 definierar flera överlagringar läggs standardkonstruktorn inte automatiskt till i klassen.
Exempel 4 – Länka konstruktorer med en delad metod
Det här exemplet visar hur du kan skriva återanvändbar delad kod för konstruktorer.
PowerShell-klasser kan inte använda konstruktorlänkning, så den här exempelklassen definierar en Init()
metod i stället. Metoden har flera överlagringar. Överlagringarna med färre parametrar anropar de mer explicita överlagringarna med standardvärden för de ospecificerade parametrarna.
class ExampleBook4 {
[string] $Name
[string] $Author
[datetime] $PublishedOn
[int] $Pages
ExampleBook4() {
$this.Init()
}
ExampleBook4([string]$Name) {
$this.Init($Name)
}
ExampleBook4([string]$Name, [string]$Author) {
$this.Init($Name, $Author)
}
ExampleBook4([string]$Name, [string]$Author, [datetime]$PublishedOn) {
$this.Init($Name, $Author, $PublishedOn)
}
ExampleBook4(
[string]$Name,
[string]$Author,
[datetime]$PublishedOn,
[int]$Pages
) {
$this.Init($Name, $Author, $PublishedOn, $Pages)
}
hidden Init() {
$this.Init('Unknown')
}
hidden Init([string]$Name) {
$this.Init($Name, 'Unknown')
}
hidden Init([string]$Name, [string]$Author) {
$this.Init($Name, $Author, (Get-Date).Date)
}
hidden Init([string]$Name, [string]$Author, [datetime]$PublishedOn) {
$this.Init($Name, $Author, $PublishedOn, 1)
}
hidden Init(
[string]$Name,
[string]$Author,
[datetime]$PublishedOn,
[int]$Pages
) {
$this.Name = $Name
$this.Author = $Author
$this.PublishedOn = $PublishedOn
$this.Pages = $Pages
}
}
[ExampleBook4]::new()
[ExampleBook4]::new('The Hobbit')
[ExampleBook4]::new('The Hobbit', 'J.R.R. Tolkien')
[ExampleBook4]::new('The Hobbit', 'J.R.R. Tolkien', (Get-Date '1937-9-21'))
[ExampleBook4]::new(
'The Hobbit',
'J.R.R. Tolkien',
(Get-Date '1937-9-21'),
310
)
Name Author PublishedOn Pages
---- ------ ----------- -----
Unknown Unknown 11/1/2023 12:00:00 AM 1
The Hobbit Unknown 11/1/2023 12:00:00 AM 1
The Hobbit J.R.R. Tolkien 11/1/2023 12:00:00 AM 1
The Hobbit J.R.R. Tolkien 9/21/1937 12:00:00 AM 1
The Hobbit J.R.R. Tolkien 9/21/1937 12:00:00 AM 310
Exempel 5 – Härledda klasskonstruktorer
I följande exempel används klasser som definierar statiska konstruktorer, standardkonstruktorer och parameteriserade konstruktorer för en basklass och en härledd klass som ärver från basklassen.
class BaseExample {
static [void] DefaultMessage([type]$Type) {
Write-Verbose "[$($Type.Name)] default constructor"
}
static [void] StaticMessage([type]$Type) {
Write-Verbose "[$($Type.Name)] static constructor"
}
static [void] ParamMessage([type]$Type, [object]$Value) {
Write-Verbose "[$($Type.Name)] param constructor ($Value)"
}
static BaseExample() { [BaseExample]::StaticMessage([BaseExample]) }
BaseExample() { [BaseExample]::DefaultMessage([BaseExample]) }
BaseExample($Value) { [BaseExample]::ParamMessage([BaseExample], $Value) }
}
class DerivedExample : BaseExample {
static DerivedExample() { [BaseExample]::StaticMessage([DerivedExample]) }
DerivedExample() { [BaseExample]::DefaultMessage([DerivedExample]) }
DerivedExample([int]$Number) : base($Number) {
[BaseExample]::ParamMessage([DerivedExample], $Number)
}
DerivedExample([string]$String) {
[BaseExample]::ParamMessage([DerivedExample], $String)
}
}
Följande block visar utförliga meddelanden för att anropa basklasskonstruktorerna. Det statiska konstruktormeddelandet genereras bara första gången en instans av klassen skapas.
PS> $VerbosePreference = 'Continue'
PS> $b = [BaseExample]::new()
VERBOSE: [BaseExample] static constructor
VERBOSE: [BaseExample] default constructor
PS> $b = [BaseExample]::new()
VERBOSE: [BaseExample] default constructor
PS> $b = [BaseExample]::new(1)
VERBOSE: [BaseExample] param constructor (1)
Nästa block visar utförliga meddelanden för att anropa de härledda klasskonstruktorerna i en ny session. Första gången en konstruktor för härledd klass anropas anropas de statiska konstruktorerna för basklassen och den härledda klassen. Dessa konstruktorer anropas inte igen i sessionen. Konstruktorerna för basklassen körs alltid före konstruktorerna för den härledda klassen.
PS> $VerbosePreference = 'Continue'
PS> $c = [DerivedExample]::new()
VERBOSE: [BaseExample] static constructor
VERBOSE: [DerivedExample] static constructor
VERBOSE: [BaseExample] default constructor
VERBOSE: [DerivedExample] default constructor
PS> $c = [DerivedExample]::new()
VERBOSE: [BaseExample] default constructor
VERBOSE: [DerivedExample] default constructor
PS> $c = [DerivedExample]::new(1)
VERBOSE: [BaseExample] param constructor (1)
VERBOSE: [DerivedExample] param constructor (1)
PS> $c = [DerivedExample]::new('foo')
VERBOSE: [BaseExample] default constructor
VERBOSE: [DerivedExample] param constructor (foo)
Konstruktorkörningsordning
När en klass instansierar körs koden för en eller flera konstruktorer.
För klasser som inte ärver från en annan klass är ordningen:
- Den statiska konstruktorn för klassen.
- Den tillämpliga konstruktoröverlagringen för klassen.
För härledda klasser som ärver från en annan klass är ordningen:
- Den statiska konstruktorn för basklassen.
- Den statiska konstruktorn för den härledda klassen.
- Om konstruktorn för den härledda klassen uttryckligen anropar en baskonstruktoröverlagring kör den konstruktorn för basklassen. Om den inte uttryckligen anropar en baskonstruktor kör den standardkonstruktorn för basklassen.
- Den tillämpliga konstruktoröverlagringen för den härledda klassen.
I samtliga fall körs statiska konstruktorer bara en gång i en session.
Ett exempel på konstruktorbeteende och ordning finns i Exempel 5.
Dolda konstruktorer
Du kan dölja konstruktorer för en klass genom att deklarera dem med nyckelordet hidden
. Dolda klasskonstruktorer är:
- Ingår inte i standardutdata för klassen.
- Ingår inte i listan över klassmedlemmar som returneras av cmdleten
Get-Member
. Om du vill visa dolda egenskaper medGet-Member
använder du parametern Force . - Visas inte i tabbslut eller IntelliSense om inte slutförandet sker i klassen som definierar den dolda egenskapen.
- Offentliga medlemmar i klassen. De kan nås och ändras. Att dölja en egenskap gör den inte privat. Den döljer bara egenskapen enligt beskrivningen i föregående punkter.
Kommentar
När du döljer en konstruktor new()
tas alternativet bort från IntelliSense och slutföranderesultat.
Mer information om nyckelordet finns i hidden
about_Hidden.
Statiska konstruktorer
Du kan definiera en konstruktor som tillhör själva klassen i stället för instanser av klassen genom att deklarera konstruktorn med nyckelordet static
.
Statiska klasskonstruktorer:
- Anropa bara första gången en instans av klassen skapas i sessionen.
- Det går inte att ha några parametrar.
- Det går inte att komma åt instansegenskaper eller -metoder med variabeln
$this
.
Konstruktorer för härledda klasser
När en klass ärver från en annan klass kan konstruktorer anropa en konstruktor från basklassen med nyckelordet base
. Om den härledda klassen inte uttryckligen anropar en konstruktor från basklassen anropas standardkonstruktorn för basklassen i stället.
Om du vill anropa en nondefault-baskonstruktor lägger du till : base(<parameters>)
efter konstruktorparametrarna och före brödtextblocket.
class <derived-class> : <base-class> {
<derived-class>(<derived-parameters>) : <base-class>(<base-parameters>) {
# initialization code
}
}
När du definierar en konstruktor som anropar en basklasskonstruktor kan parametrarna vara något av följande objekt:
- Variabeln för valfri parameter i den härledda klasskonstruktorn.
- Alla statiska värden.
- Alla uttryck som utvärderas till ett värde av parametertypen.
Ett exempel på konstruktorer i en härledd klass finns i Exempel 5.
Länka konstruktorer
Till skillnad från C# kan PowerShell-klasskonstruktorer inte använda länkning med syntaxen : this(<parameters>)
. Om du vill minska koddupliceringen använder du en dold Init()
metod med flera överlagringar med samma effekt. Exempel 4 visar en klass med det här mönstret.
Lägga till instansegenskaper och metoder med Update-TypeData
Förutom att deklarera egenskaper och metoder direkt i klassdefinitionen kan du definiera egenskaper för instanser av en klass i den statiska konstruktorn med hjälp av cmdleten Update-TypeData
.
Använd det här kodfragmentet som utgångspunkt för mönstret. Ersätt platshållartexten i vinkelparenteser efter behov.
class <class-name> {
static [hashtable[]] $MemberDefinitions = @(
@{
Name = '<member-name>'
MemberType = '<member-type>'
Value = <member-definition>
}
)
static <class-name>() {
$TypeName = [<class-name>].Name
foreach ($Definition in [<class-name>]::MemberDefinitions) {
Update-TypeData -TypeName $TypeName @Definition
}
}
}
Dricks
Cmdleten Add-Member
kan lägga till egenskaper och metoder i en klass i icke-statiska konstruktorer, men cmdleten körs varje gång konstruktorn anropas. Om du använder Update-TypeData
den statiska konstruktorn ser du till att koden för att lägga till medlemmar i klassen bara behöver köras en gång i en session.
Lägg bara till egenskaper i klassen i icke-statiska konstruktorer när de inte kan definieras med Update-TypeData
, som skrivskyddade egenskaper.
Mer information om hur du definierar instansmetoder med Update-TypeData
finns i about_Classes_Methods. Mer information om hur du definierar instansegenskaper med Update-TypeData
finns i about_Classes_Properties.
Begränsningar
PowerShell-klasskonstruktorer har följande begränsningar:
Konstruktorlänkning implementeras inte.
Lösning: Definiera dolda
Init()
metoder och anropa dem inifrån konstruktorerna.Konstruktorparametrar kan inte använda några attribut, inklusive valideringsattribut.
Lösning: Tilldela om parametrarna i konstruktorns brödtext med valideringsattributet.
Konstruktorparametrar kan inte definiera standardvärden. Parametrarna är alltid obligatoriska.
Lösning: Inga.
Om någon överlagring av en konstruktor är dold behandlas även varje överlagring för konstruktorn som dold.
Lösning: Inga.
Se även
Feedback
https://aka.ms/ContentUserFeedback.
Kommer snart: Under hela 2024 kommer vi att fasa ut GitHub-problem som feedbackmekanism för innehåll och ersätta det med ett nytt feedbacksystem. Mer information finns i:Skicka och visa feedback för