about_Classes_Constructors
Kurze Beschreibung
Beschreibt, wie Konstruktoren für PowerShell-Klassen definiert werden.
Lange Beschreibung
Mit Konstruktoren können Sie Standardwerte festlegen und die Objektlogik zum Zeitpunkt der Erstellung der Instanz der Klasse überprüfen. Konstruktoren haben denselben Namen wie die Klasse. Konstruktoren verfügen möglicherweise über Parameter, um die Datenmmber des neuen Objekts zu initialisieren.
PowerShell-Klassenkonstruktoren werden als spezielle Methoden für die Klasse definiert. Sie verhalten sich mit den PowerShell-Klassenmethoden mit den folgenden Ausnahmen:
- Konstruktoren haben keinen Ausgabetyp. Sie können die
return
Schlüsselwort (keyword) nicht verwenden. - Konstruktoren haben immer denselben Namen wie die Klasse.
- Konstruktoren können nicht direkt aufgerufen werden. Sie werden nur ausgeführt, wenn eine Instanz erstellt wird.
- Konstruktoren werden nie in der Ausgabe für das
Get-Member
Cmdlet angezeigt.
Weitere Informationen zu PowerShell-Klassenmethoden finden Sie unter about_Classes_Methods.
Die Klasse kann null oder mehr Konstruktoren definiert haben. Wenn kein Konstruktor definiert ist, erhält die Klasse einen standardparameterlosen Konstruktor. Dieser Konstruktor initialisiert alle Member mit ihren Standardwerten. Objekttypen und Zeichenfolgen werden NULL-Werte angegeben. Wenn Sie den Konstruktor definieren, wird kein standardparameterloser Konstruktor erstellt. Erstellen Sie bei Bedarf einen parameterlosen Konstruktor.
Sie können auch einen parameterlosen statischen Konstruktor definieren.
Syntax
Klassenkonstruktoren verwenden die folgenden Syntaxen:
Standardkonstruktorsyntax
<class-name> () [: base([<params>])] {
<body>
}
Syntax statischer Konstruktor
static <class-name> () [: base([<params>])] {
<body>
}
Parametrisierte Konstruktorsyntax (einzeilige)
<class-name> ([[<parameter-type>]$<parameter-name>[, [<parameter-type>]$<parameter-name>...]]) [: base([<params>])] {
<body>
}
Parametrisierte Konstruktorsyntax (multiline)
<class-name> (
[<parameter-type>]$<parameter-name>[,
[<parameter-type>]$<parameter-name>...]
) [: base([<params>])] {
<body>
}
Beispiele
Beispiel 1: Definieren einer Klasse mit dem Standardkonstruktor
Die ExampleBook1-Klasse definiert keinen Konstruktor. Stattdessen wird der automatische Standardkonstruktor verwendet.
class ExampleBook1 {
[string] $Name
[string] $Author
[int] $Pages
[datetime] $PublishedOn
}
[ExampleBook1]::new()
Name Author Pages PublishedOn
---- ------ ----- -----------
0 1/1/0001 12:00:00 AM
Hinweis
Der Standardwert für die Eigenschaften Name und Autor besteht $null
darin, dass sie als Zeichenfolgen eingegeben werden, bei denen es sich um einen Verweistyp handelt. Die anderen Eigenschaften weisen den Standardwert für ihren definierten Typ auf, da sie Werttypeigenschaften sind. Weitere Informationen zu den Standardwerten für Eigenschaften finden Sie unter "Standardwerte" in about_Classes_Properties.
Beispiel 2: Überschreiben des Standardkonstruktors
ExampleBook2 definiert explizit den Standardkonstruktor und legt die Werte für "PublishedOn " auf das aktuelle Datum und "Pages " fest 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
Beispiel 3 : Definieren von Konstruktorüberladungen
Die ExampleBook3-Klasse definiert drei Konstruktorüberladungen, sodass Benutzer eine Instanz der Klasse aus einer Hashtabelle erstellen können, indem sie jeden Eigenschaftswert übergeben und den Namen des Buchs und Autors übergeben. Die Klasse definiert nicht den Standardkonstruktor.
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".
Durch Aufrufen des Standardkonstruktors wird eine Methoden exception zurückgegeben. Der automatische Standardkonstruktor wird nur für eine Klasse definiert, wenn die Klasse keine Konstruktoren definiert. Da ExampleBook3 mehrere Überladungen definiert, wird der Standardkonstruktor nicht automatisch der Klasse hinzugefügt.
Beispiel 4 : Verketten von Konstruktoren mit einer freigegebenen Methode
In diesem Beispiel wird gezeigt, wie Sie wiederverwendbaren freigegebenen Code für Konstruktoren schreiben können.
PowerShell-Klassen können keine Konstruktorkette verwenden, daher definiert diese Beispielklasse stattdessen eine Init()
Methode. Für die -Methode gibt es mehrere Überladungen. Die Überladungen mit weniger Parametern rufen die expliziteren Überladungen mit Standardwerten für die nicht angegebenen Parameter auf.
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
Beispiel 5 : Abgeleitete Klassenkonstruktoren
In den folgenden Beispielen werden Klassen verwendet, die die statischen, standard- und parametrisierten Konstruktoren für eine Basisklasse und eine abgeleitete Klasse definieren, die von der Basisklasse erbt.
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)
}
}
Der folgende Block zeigt das ausführliche Messaging zum Aufrufen der Basisklassenkonstruktoren. Die statische Konstruktornachricht wird nur ausgegeben, wenn eine Instanz der Klasse zum ersten Mal erstellt wird.
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)
Der nächste Block zeigt das ausführliche Messaging zum Aufrufen der abgeleiteten Klassenkonstruktoren in einer neuen Sitzung. Wenn ein abgeleiteter Klassenkonstruktor zum ersten Mal aufgerufen wird, werden die statischen Konstruktoren für die Basisklasse und die abgeleitete Klasse aufgerufen. Diese Konstruktoren werden in der Sitzung nicht erneut aufgerufen. Die Konstruktoren für die Basisklasse werden immer vor den Konstruktoren für die abgeleitete Klasse ausgeführt.
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)
Konstruktor wird sortierung ausgeführt
Wenn eine Klasse instanziiert, wird der Code für einen oder mehrere Konstruktoren ausgeführt.
Bei Klassen, die nicht von einer anderen Klasse erben, lautet die Sortierung:
- Der statische Konstruktor für die Klasse.
- Die entsprechende Konstruktorüberladung für die Klasse.
Bei abgeleiteten Klassen, die von einer anderen Klasse erben, lautet die Sortierung:
- Der statische Konstruktor für die Basisklasse.
- Der statische Konstruktor für die abgeleitete Klasse.
- Wenn der abgeleitete Klassenkonstruktor explizit eine Basiskonstruktorüberladung aufruft, wird dieser Konstruktor für die Basisklasse ausgeführt. Wenn kein Basiskonstruktor explizit aufgerufen wird, wird der Standardkonstruktor für die Basisklasse ausgeführt.
- Die entsprechende Konstruktorüberladung für die abgeleitete Klasse.
In allen Fällen werden statische Konstruktoren nur einmal in einer Sitzung ausgeführt.
Ein Beispiel für Konstruktorverhalten und -sortierung finden Sie unter Beispiel 5.
Ausgeblendete Konstruktoren
Sie können Konstruktoren einer Klasse ausblenden, indem Sie sie mit dem hidden
Schlüsselwort (keyword) deklarieren. Ausgeblendete Klassenkonstruktoren sind:
- Nicht in der Standardausgabe für die Klasse enthalten.
- Nicht in der Liste der vom Cmdlet zurückgegebenen
Get-Member
Klassenmber enthalten. Um ausgeblendete Eigenschaften mitGet-Member
anzuzeigen, verwenden Sie den Force-Parameter . - Wird nicht im Abschluss der Registerkarte oder IntelliSense angezeigt, es sei denn, der Abschluss erfolgt in der Klasse, die die ausgeblendete Eigenschaft definiert.
- Öffentliche Member der Klasse. Auf sie kann zugegriffen und geändert werden. Durch das Ausblenden einer Eigenschaft wird sie nicht privat. Sie blendet die Eigenschaft nur aus, wie in den vorherigen Punkten beschrieben.
Hinweis
Wenn Sie einen Konstruktor ausblenden, wird die new()
Option aus IntelliSense- und Abschlussergebnissen entfernt.
Weitere Informationen zum hidden
Schlüsselwort (keyword) finden Sie unter about_Hidden.
Statische Konstruktoren
Sie können einen Konstruktor als Zugehörigkeit zur Klasse selbst und nicht als Instanzen der Klasse definieren, indem Sie den Konstruktor mit dem static
Schlüsselwort (keyword) deklarieren.
Statische Klassenkonstruktoren:
- Rufen Sie nur das erste Mal auf, wenn eine Instanz der Klasse in der Sitzung erstellt wird.
- Es können keine Parameter vorhanden sein.
- Auf Instanzeigenschaften oder -methoden mit der
$this
Variablen kann nicht zugegriffen werden.
Konstruktoren für abgeleitete Klassen
Wenn eine Klasse von einer anderen Klasse erbt, können Konstruktoren einen Konstruktor aus der Basisklasse mit dem base
Schlüsselwort (keyword) aufrufen. Wenn die abgeleitete Klasse keinen Konstruktor aus der Basisklasse explizit aufruft, ruft sie stattdessen den Standardkonstruktor für die Basisklasse auf.
Um einen nicht standardmäßigen Basiskonstruktor aufzurufen, fügen Sie : base(<parameters>)
nach den Konstruktorparametern und vor dem Textkörperblock hinzu.
class <derived-class> : <base-class> {
<derived-class>(<derived-parameters>) : <base-class>(<base-parameters>) {
# initialization code
}
}
Beim Definieren eines Konstruktors, der einen Basisklassenkonstruktor aufruft, können die Parameter eines der folgenden Elemente sein:
- Die Variable eines parameters für den abgeleiteten Klassenkonstruktor.
- Ein beliebiger statischer Wert.
- Jeder Ausdruck, der zu einem Wert des Parametertyps ausgewertet wird.
Ein Beispiel für Konstruktoren für eine abgeleitete Klasse finden Sie unter Beispiel 5.
Verketten von Konstruktoren
Im Gegensatz zu C# können PowerShell-Klassenkonstruktoren keine Verkettung mit der : this(<parameters>)
Syntax verwenden. Um die Codeduplizierung zu reduzieren, verwenden Sie eine ausgeblendete Init()
Methode mit mehreren Überladungen zum gleichen Effekt. Beispiel 4 zeigt eine Klasse mit diesem Muster.
Hinzufügen von Instanzeigenschaften und -methoden mit Update-TypeData
Über das direkte Deklarieren von Eigenschaften und Methoden in der Klassendefinition hinaus können Sie Eigenschaften für Instanzen einer Klasse im statischen Konstruktor mithilfe des Update-TypeData
Cmdlets definieren.
Verwenden Sie diesen Codeausschnitt als Ausgangspunkt für das Muster. Ersetzen Sie den Platzhaltertext nach Bedarf in winkeln Klammern.
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
}
}
}
Tipp
Das Add-Member
Cmdlet kann einer Klasse in nicht statischen Konstruktoren Eigenschaften und Methoden hinzufügen, das Cmdlet wird jedoch jedes Mal ausgeführt, wenn der Konstruktor aufgerufen wird. Die Verwendung Update-TypeData
im statischen Konstruktor stellt sicher, dass der Code zum Hinzufügen der Member zur Klasse nur einmal in einer Sitzung ausgeführt werden muss.
Fügen Sie der Klasse nur Eigenschaften in nicht statischen Konstruktoren hinzu, wenn sie nicht mit Update-TypeData
schreibgeschützten Eigenschaften definiert werden können.
Weitere Informationen zum Definieren von Instanzmethoden mit Update-TypeData
, finden Sie unter about_Classes_Methods. Weitere Informationen zum Definieren von Instanzeigenschaften mit Update-TypeData
, finden Sie unter about_Classes_Properties.
Begrenzungen
PowerShell-Klassenkonstruktoren haben die folgenden Einschränkungen:
Die Konstruktorkette wird nicht implementiert.
Problemumgehung: Definieren Sie ausgeblendete
Init()
Methoden, und rufen Sie sie aus den Konstruktoren auf.Konstruktorparameter können keine Attribute verwenden, einschließlich Validierungsattributen.
Problemumgehung: Weisen Sie die Parameter im Konstruktortext erneut mit dem Überprüfungsattribut zu.
Konstruktorparameter können keine Standardwerte definieren. Die Parameter sind immer obligatorisch.
Abhilfen: Keine.
Wenn eine Überladung eines Konstruktors ausgeblendet ist, wird jede Überladung für den Konstruktor ebenfalls als ausgeblendet behandelt.
Abhilfen: Keine.
Weitere Informationen
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für