about_Classes
Kurze Beschreibung
Beschreibt, wie Sie Klassen zum Erstellen eigener benutzerdefinierter Typen verwenden können.
Lange Beschreibung
Ab Version 5.0 verfügt PowerShell über eine formale Syntax zum Definieren von Klassen und anderen benutzerdefinierten Typen. Durch das Hinzufügen von Klassen können Entwickler und IT-Experten PowerShell für eine breitere Palette von Anwendungsfällen nutzen.
Eine Klassendeklaration ist ein Blueprint zum Erstellen von Instanzen von Objekten zur Laufzeit. Wenn Sie eine Klasse definieren, ist der Klassenname der Name des Typs. Wenn Sie beispielsweise eine Klasse namens "Device" deklarieren und eine Variable $dev
in eine neue Instanz von Device initialisieren, $dev
handelt es sich um ein Objekt oder eine Instanz vom Typ "Device". Jede Instanz von Device kann unterschiedliche Werte in ihren Eigenschaften aufweisen.
Unterstützte Szenarios
- Definieren von benutzerdefinierten Typen in PowerShell mithilfe objektorientierter Programmiersemantik wie Klassen, Eigenschaften, Methoden, Vererbung usw.
- Definieren Sie DSC-Ressourcen und die zugehörigen Typen mithilfe der PowerShell-Sprache.
- Definieren Sie benutzerdefinierte Attribute, um Variablen, Parameter und benutzerdefinierte Typdefinitionen zu versehen.
- Definieren Sie benutzerdefinierte Ausnahmen, die von ihrem Typnamen abgefangen werden können.
Syntax
Definitionssyntax
Klassendefinitionen verwenden die folgende Syntax:
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> ...]
}
Instanziierungssyntax
Verwenden Sie eine der folgenden Syntaxen, um eine Instanz einer Klasse zu instanziieren:
[$<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>]}
Hinweis
Bei Verwendung der [<class-name>]::new()
Syntax sind Klammern um den Klassennamen obligatorisch. Die Klammern signalisieren eine Typdefinition für PowerShell.
Die Hashtabellensyntax funktioniert nur für Klassen mit einem Standardkonstruktor, der keine Parameter erwartet. Sie erstellt eine Instanz der Klasse mit dem Standardkonstruktor und weist dann den Instanzeneigenschaften die Schlüssel-Wert-Paare zu. Wenn ein Schlüssel in der Hashtabelle kein gültiger Eigenschaftsname ist, löst PowerShell einen Fehler aus.
Beispiele
Beispiel 1 – Minimale Definition
In diesem Beispiel wird die Mindestsyntax veranschaulicht, die zum Erstellen einer verwendbaren Klasse erforderlich ist.
class Device {
[string]$Brand
}
$dev = [Device]::new()
$dev.Brand = "Fabrikam, Inc."
$dev
Brand
-----
Fabrikam, Inc.
Beispiel 2 : Klasse mit Instanzmitgliedern
In diesem Beispiel wird eine Book-Klasse mit mehreren Eigenschaften, Konstruktoren und Methoden definiert. Jedes definierte Element ist ein Instanzmemm , kein statisches Element. Auf die Eigenschaften und Methoden kann nur über eine erstellte Instanz der Klasse zugegriffen werden.
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))"
}
}
Der folgende Codeausschnitt erstellt eine Instanz der Klasse und zeigt, wie sie sich verhält. Nach dem Erstellen einer Instanz der Book-Klasse verwendet das Beispiel die GetReadingTime()
Und GetPublishedAge()
Methoden, um eine Nachricht über das Buch zu schreiben.
$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.
Beispiel 3 : Klasse mit statischen Membern
Die BookList-Klasse in diesem Beispiel baut auf der Book-Klasse in Beispiel 2 auf. Obwohl die BookList-Klasse nicht als statisch gekennzeichnet werden kann, definiert die Implementierung nur die statische Books-Eigenschaft und eine Reihe statischer Methoden zum Verwalten dieser Eigenschaft.
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)
}
}
}
Nachdem BookList definiert ist, kann das Buch aus dem vorherigen Beispiel der Liste hinzugefügt werden.
$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}
Der folgende Codeausschnitt ruft die statischen Methoden für die Klasse auf.
[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
Beispiel 4 – Klassendefinition mit und ohne Runspace-Affinität
Die ShowRunspaceId()
Methode meldet [UnsafeClass]
unterschiedliche Thread-IDs, aber dieselbe Runspace-ID. Schließlich ist der Sitzungszustand beschädigt, was zu einem Fehler führt, z Global scope cannot be removed
. B. .
# 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($_)
}
}
Hinweis
Dieses Beispiel wird in einer Endlosschleife ausgeführt. Drücken Sie STRG+C, um die Ausführung zu beenden.
Die ShowRunspaceId()
Methode von [SafeClass]
Berichten über verschiedene Thread- und Runspace-IDs.
# 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($_)
}
}
Hinweis
Dieses Beispiel wird in einer Endlosschleife ausgeführt. Drücken Sie STRG+C, um die Ausführung zu beenden.
Klasseneigenschaften
Eigenschaften sind Variablen, die im Klassenbereich deklariert werden. Eine Eigenschaft kann von jedem integrierten Typ oder einer Instanz einer anderen Klasse sein. Klassen können null oder mehr Eigenschaften aufweisen. Klassen haben keine maximale Eigenschaftsanzahl.
Weitere Informationen finden Sie unter about_Classes_Properties.
Klassenmethoden
Methoden definieren die Aktionen, die von einer Klasse ausgeführt werden können. Methoden können Parameter verwenden, die Eingabedaten angeben. Methoden definieren immer einen Ausgabetyp. Wenn eine Methode keine Ausgabe zurückgibt, muss sie den Ausgabetyp "Void" aufweisen. Wenn eine Methode keinen Ausgabetyp explizit definiert, lautet der Ausgabetyp der Methode "Void".
Weitere Informationen finden Sie unter about_Classes_Methods.
Klassenkonstruktoren
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.
Weitere Informationen finden Sie unter about_Classes_Constructors.
Ausgeblendetes Schlüsselwort
Das hidden
Schlüsselwort blendet ein Klassenelement aus. Der Member ist weiterhin für den Benutzer zugänglich und steht in allen Bereichen zur Verfügung, in denen das Objekt verfügbar ist.
Ausgeblendete Member werden vom Cmdlet ausgeblendet und können nicht mithilfe des Get-Member
Tabstoppabschlusses oder IntelliSense außerhalb der Klassendefinition angezeigt werden.
Das hidden
Schlüsselwort gilt nur für Klassenmember, nicht für eine Klasse selbst.
Ausgeblendete Klassenmmber 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 Member mitGet-Member
anzuzeigen, verwenden Sie den Parameter Force . - Wird nicht im Abschluss der Registerkarte oder IntelliSense angezeigt, es sei denn, der Abschluss erfolgt in der Klasse, die das ausgeblendete Element definiert.
- Öffentliche Member der Klasse. Auf sie kann zugegriffen, geerbt und geändert werden. Durch das Ausblenden eines Mitglieds wird es nicht privat. Es blendet das Element nur aus, wie in den vorherigen Punkten beschrieben.
Hinweis
Wenn Sie eine Überladung für eine Methode ausblenden, wird diese Methode aus IntelliSense, Abschlussergebnissen und der Standardausgabe für Get-Member
.
Wenn Sie einen Konstruktor ausblenden, wird die new()
Option aus IntelliSense- und Abschlussergebnissen entfernt.
Weitere Informationen zum Schlüsselwort finden Sie unter about_Hidden. Weitere Informationen zu ausgeblendeten Eigenschaften finden Sie unter about_Classes_Properties. Weitere Informationen zu ausgeblendeten Methoden finden Sie unter about_Classes_Methods. Weitere Informationen zu ausgeblendeten Konstruktoren finden Sie unter about_Classes_Constructors.
Statisches Schlüsselwort
Das static
Schlüsselwort definiert eine Eigenschaft oder methode, die in der Klasse vorhanden ist und keine Instanz benötigt.
Eine statische Eigenschaft ist immer verfügbar, unabhängig von der Klasseninstanziierung. Eine statische Eigenschaft wird für alle Instanzen der Klasse freigegeben. Eine statische Methode ist immer verfügbar. Alle statischen Eigenschaften werden für die gesamte Sitzungsspanne live ausgeführt.
Das static
Schlüsselwort gilt nur für Klassenmember, nicht für eine Klasse selbst.
Weitere Informationen zu statischen Eigenschaften finden Sie unter about_Classes_Properties. Weitere Informationen zu statischen Methoden finden Sie unter about_Classes_Methods. Weitere Informationen zu statischen Konstruktoren finden Sie unter about_Classes_Constructors.
Vererbung in PowerShell-Klassen
Sie können eine Klasse erweitern, indem Sie eine neue Klasse erstellen, die von einer vorhandenen Klasse abgeleitet wird. Die abgeleitete Klasse erbt die Eigenschaften und Methoden der Basisklasse. Sie können die Basisklassenmmber nach Bedarf hinzufügen oder außer Kraft setzen.
PowerShell unterstützt keine mehrfache Vererbung. Klassen können nicht direkt von mehreren Klassen erben.
Klassen können auch von Schnittstellen erben, die einen Vertrag definieren. Eine Klasse, die von einer Schnittstelle erbt, muss diesen Vertrag implementieren. In diesem Fall kann die Klasse wie jede andere Klasse verwendet werden, die diese Schnittstelle implementiert.
Weitere Informationen zum Ableiten von Klassen, die von einer Basisklasse erben oder Schnittstellen implementieren, finden Sie unter about_Classes_Inheritance.
NoRunspaceAffinity-Attribut
Ein Runspace ist die Betriebssystemumgebung für die von PowerShell aufgerufenen Befehle. Diese Umgebung enthält die Befehle und Daten, die derzeit vorhanden sind, sowie alle derzeit geltenden Spracheinschränkungen.
Standardmäßig ist eine PowerShell-Klasse mit dem Runspace verbunden, in dem sie erstellt wird. Die Verwendung einer PowerShell-Klasse in ForEach-Object -Parallel
ist nicht sicher.
Methodenaufrufe für die Klasse werden zurück zum Runspace ge marshallt, wo es erstellt wurde, was den Zustand des Runspace beschädigen oder einen Deadlock verursachen kann.
Durch Hinzufügen des NoRunspaceAffinity
Attributs zur Klassendefinition wird sichergestellt, dass die PowerShell-Klasse nicht mit einem bestimmten Runspace verbunden ist. Methodenaufrufe, sowohl Instanzen als auch statisch, verwenden den Runspace des ausgeführten Threads und den aktuellen Sitzungszustand des Threads.
Das Attribut wurde in PowerShell 7.4 hinzugefügt.
Eine Abbildung des Verhaltensunterschieds für Klassen mit und ohne Attribut NoRunspaceAffinity
finden Sie in Beispiel 4.
Exportieren von Klassen mit Typbeschleunigern
PowerShell-Module exportieren standardmäßig nicht automatisch Klassen und Enumerationen, die in PowerShell definiert sind. Die benutzerdefinierten Typen sind außerhalb des Moduls nicht verfügbar, ohne eine using module
Anweisung aufzurufen.
Wenn ein Modul jedoch Zugriffstasten hinzufügt, sind diese Zugriffstasten sofort in der Sitzung verfügbar, nachdem Benutzer das Modul importiert haben.
Hinweis
Das Hinzufügen von Typbeschleunigern zur Sitzung verwendet eine interne (nicht öffentliche) API. Die Verwendung dieser API kann Konflikte verursachen. Das unten beschriebene Muster löst einen Fehler aus, wenn beim Importieren des Moduls bereits eine Typbeschleuniger mit demselben Namen vorhanden ist. Außerdem werden die Typtasten entfernt, wenn Sie das Modul aus der Sitzung entfernen.
Dieses Muster stellt sicher, dass die Typen in einer Sitzung verfügbar sind. Beim Erstellen einer Skriptdatei in VS Code wirkt sich dies nicht auf IntelliSense oder den Abschluss aus.
Um IntelliSense- und Abschlussvorschläge für benutzerdefinierte Typen in VS Code abzurufen, müssen Sie oben im Skript eine using module
Anweisung hinzufügen.
Das folgende Muster zeigt, wie Sie PowerShell-Klassen und -Enumerationen als Typbeschleuniger in einem Modul registrieren können. Fügen Sie den Codeausschnitt nach allen Typdefinitionen zum Stammskriptmodul hinzu. Stellen Sie sicher, dass die $ExportableTypes
Variable die einzelnen Typen enthält, die Sie benutzern beim Importieren des Moduls zur Verfügung stellen möchten. Der andere Code erfordert keine Bearbeitung.
# 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()
Wenn Benutzer das Modul importieren, sind alle Typen, die den Typbeschleunigern für die Sitzung hinzugefügt wurden, sofort für IntelliSense und abschluss verfügbar. Wenn das Modul entfernt wird, sind dies die Typtasten.
Manuelles Importieren von Klassen aus einem PowerShell-Modul
Import-Module
und die #requires
Anweisung importiert nur die Modulfunktionen, Aliase und Variablen, wie vom Modul definiert. Klassen werden nicht importiert.
Wenn ein Modul Klassen und Enumerationen definiert, aber keine Typbeschleuniger für diese Typen hinzugibt, verwenden Sie eine using module
Anweisung, um sie zu importieren.
Die using module
Anweisung importiert Klassen und Enumerationen aus dem Stammmodul (ModuleToProcess
) eines Skriptmoduls oder binären Moduls. Es werden klassen, die in geschachtelten Modulen oder Klassen definiert sind, die in Skripts definiert sind, die punktgequellt in das Stammmodul definiert sind, nicht konsistent importiert. Definieren Sie Klassen, die Benutzern außerhalb des Moduls direkt im Stammmodul zur Verfügung stehen sollen.
Weitere Informationen zur using
Anweisung finden Sie unter about_Using.
Laden von neu geänderten Code während der Entwicklung
Bei der Entwicklung eines Skriptmoduls ist es üblich, Änderungen am Code vorzunehmen und dann die neue Version des Moduls mit Import-Module
dem Parameter Force zu laden. Das Neuladen des Moduls funktioniert nur für Änderungen an Funktionen im Stammmodul. Import-Module
lädt keine geschachtelten Module neu. Außerdem gibt es keine Möglichkeit, aktualisierte Klassen zu laden.
Um sicherzustellen, dass Sie die neueste Version ausführen, müssen Sie eine neue Sitzung starten.
Klassen und Enumerationen, die in PowerShell definiert und mit einer using
Anweisung importiert wurden, können nicht entladen werden.
Eine weitere gängige Entwicklungspraxis besteht darin, Ihren Code in verschiedene Dateien zu trennen. Wenn Sie eine Funktion in einer Datei haben, die Klassen verwendet, die in einem anderen Modul definiert sind, sollten Sie die using module
Anweisung verwenden, um sicherzustellen, dass die Funktionen über die erforderlichen Klassendefinitionen verfügen.
Der PSReference-Typ wird von Klassenmitgliedern nicht unterstützt.
Die [ref]
Typbeschleuniger ist kurz für die PSReference-Klasse . Die Verwendung [ref]
zum Eingeben eines Klassenelements schlägt im Hintergrund fehl. APIs, die Parameter verwenden [ref]
, können nicht mit Klassenmitgliedern verwendet werden. Die PSReference-Klasse wurde entwickelt, um COM-Objekte zu unterstützen. COM-Objekte weisen Fälle auf, in denen Sie einen Wert per Verweis übergeben müssen.
Weitere Informationen finden Sie unter PSReference-Klasse.
Begrenzungen
Die folgenden Listen enthalten Einschränkungen zum Definieren von PowerShell-Klassen und zur Problemumgehung für diese Einschränkungen, falls vorhanden.
Allgemeine Einschränkungen
Klassenmitglieder können PSReference nicht als typ verwenden.
Abhilfen: Keine.
PowerShell-Klassen können in einer Sitzung nicht entladen oder neu geladen werden.
Problemumgehung: Starten einer neuen Sitzung.
PowerShell-Klassen, die in einem Modul definiert sind, werden nicht automatisch importiert.
Problemumgehung: Fügen Sie die definierten Typen zur Liste der Typbeschleuniger im Stammmodul hinzu. Dadurch werden die Typen beim Modulimport verfügbar.
Die
hidden
Schlüsselwörterstatic
gelten nur für Klassenmember, keine Klassendefinition.Abhilfen: Keine.
Standardmäßig sind PowerShell-Klassen nicht sicher für die parallele Ausführung über Runspaces hinweg. Wenn Sie Methoden für eine Klasse aufrufen, marshallt PowerShell die Aufrufe zurück zum Runspace , in dem die Klasse erstellt wurde, wodurch der Zustand des Runspace beschädigt oder ein Deadlock verursacht werden kann.
Problemumgehung: Fügen Sie das
NoRunspaceAffinity
Attribut zur Klassendeklaration hinzu.
Konstruktorbeschrä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.
Methodenbeschränkungen
Methodenparameter können keine Attribute verwenden, einschließlich Überprüfungsattributen.
Problemumgehung: Ordnen Sie die Parameter im Methodentext erneut mit dem Überprüfungsattribut zu, oder definieren Sie die Methode im statischen Konstruktor mit dem
Update-TypeData
Cmdlet.Methodenparameter können keine Standardwerte definieren. Die Parameter sind immer obligatorisch.
Problemumgehung: Definieren Sie die Methode im statischen Konstruktor mit dem
Update-TypeData
Cmdlet.Methoden sind immer öffentlich, auch wenn sie ausgeblendet sind. Sie können überschrieben werden, wenn die Klasse geerbt wird.
Abhilfen: Keine.
Wenn eine Überladung einer Methode ausgeblendet ist, wird jede Überladung für diese Methode ebenfalls als ausgeblendet behandelt.
Abhilfen: Keine.
Eigenschaftseinschränkungen
Statische Eigenschaften sind immer änderbar. PowerShell-Klassen können unveränderliche statische Eigenschaften nicht definieren.
Abhilfen: Keine.
Eigenschaften können das ValidateScript-Attribut nicht verwenden, da Klasseneigenschaften-Attributargumente Konstanten sein müssen.
Problemumgehung: Definieren Sie eine Klasse, die vom ValidateArgumentsAttribute-Typ erbt, und verwenden Sie stattdessen dieses Attribut.
Direkt deklarierte Eigenschaften können keine benutzerdefinierten Getter- und Setterimplementierungen definieren.
Problemumgehung: Definieren Sie eine ausgeblendete Eigenschaft, und definieren
Update-TypeData
Sie die sichtbare Getter- und Setterlogik.Eigenschaften können das Alias-Attribut nicht verwenden. Das Attribut gilt nur für Parameter, Cmdlets und Funktionen.
Problemumgehung: Verwenden Sie das
Update-TypeData
Cmdlet, um Aliase in den Klassenkonstruktoren zu definieren.Wenn eine PowerShell-Klasse mit dem
ConvertTo-Json
Cmdlet in JSON konvertiert wird, enthält die Ausgabe-JSON alle ausgeblendeten Eigenschaften und deren Werte.Abhilfen: Keine
Vererbungseinschränkungen
PowerShell unterstützt das Definieren von Schnittstellen im Skriptcode nicht.
Problemumgehung: Definieren von Schnittstellen in C# und Verweisen auf die Assembly, die die Schnittstellen definiert.
PowerShell-Klassen können nur von einer Basisklasse erben.
Problemumgehung: Die Klassenvererbung ist transitiv. Eine abgeleitete Klasse kann von einer anderen abgeleiteten Klasse erben, um die Eigenschaften und Methoden einer Basisklasse abzurufen.
Beim Erben von einer generischen Klasse oder Schnittstelle muss der Typparameter für das generische Element bereits definiert sein. Eine Klasse kann sich nicht als Typparameter für eine Klasse oder Schnittstelle definieren.
Problemumgehung: Um von einer generischen Basisklasse oder Schnittstelle abzuleiten, definieren Sie den benutzerdefinierten Typ in einer anderen
.psm1
Datei, und verwenden Sie dieusing module
Anweisung, um den Typ zu laden. Es gibt keine Problemumgehung für einen benutzerdefinierten Typ, um sich selbst als Typparameter zu verwenden, wenn er von einer generischen Erbung erbt.