about_Classes

Krátký popis

Popisuje, jak můžete pomocí tříd vytvořit vlastní typy.

Dlouhý popis

Počínaje verzí 5.0 má PowerShell formální syntaxi pro definování tříd a dalších uživatelsky definovaných typů. Přidáním tříd můžou vývojáři a IT specialisté využít PowerShell pro širší škálu případů použití.

Deklarace třídy je podrobný plán, který se používá k vytváření instancí objektů za běhu. Když definujete třídu, název třídy je název typu. Pokud například deklarujete třídu s názvem Device a inicializujete proměnnou $dev na novou instanci zařízení, $dev je objekt nebo instance typu Device. Každá instance zařízení může mít ve svých vlastnostech různé hodnoty.

Podporované scénáře

  • Definujte vlastní typy v PowerShellu pomocí sémantiky objektově orientovaného programování, jako jsou třídy, vlastnosti, metody, dědičnost atd.
  • Definujte prostředky DSC a jejich přidružené typy pomocí jazyka PowerShellu.
  • Definujte vlastní atributy pro dekoraci proměnných, parametrů a definic vlastních typů.
  • Definujte vlastní výjimky, které lze zachytit podle názvu jejich typu.

Syntaxe

Syntaxe definice

Definice tříd používají následující syntaxi:

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> ...]
}

Syntaxe vytváření instancí

K vytvoření instance instance třídy použijte jednu z následujících syntaxí:

[$<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>]}

Poznámka:

Při použití [<class-name>]::new() syntaxe jsou závorky kolem názvu třídy povinné. Hranaté závorky signalizují definici typu pro PowerShell.

Syntaxe hashtable funguje pouze pro třídy, které mají výchozí konstruktor, který neočekává žádné parametry. Vytvoří instanci třídy s výchozím konstruktorem a pak přiřadí páry klíč-hodnota k vlastnostem instance. Pokud některý klíč v hashtable není platným názvem vlastnosti, PowerShell vyvolá chybu.

Příklady

Příklad 1 – minimální definice

Tento příklad ukazuje minimální syntaxi potřebnou k vytvoření použitelné třídy.

class Device {
    [string]$Brand
}

$dev = [Device]::new()
$dev.Brand = "Fabrikam, Inc."
$dev
Brand
-----
Fabrikam, Inc.

Příklad 2 – třída se členy instance

Tento příklad definuje třídu Knihy s několika vlastnostmi, konstruktory a metodami. Každý definovaný člen je členem instance , nikoli statickým členem. K vlastnostem a metodám lze přistupovat pouze prostřednictvím vytvořené instance třídy.

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))"
    }
}

Následující fragment kódu vytvoří instanci třídy a ukáže, jak se chová. Po vytvoření instance třídy Book se v příkladu používají GetReadingTime() a GetPublishedAge() metody k napsání zprávy o knize.

$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.

Příklad 3 – třída se statickými členy

Třída BookList v tomto příkladu vychází z třídy Knihy v příkladu 2. I když nelze třídu BookList označit jako statickou, implementace definuje pouze statickou vlastnost Books a sadu statických metod pro správu této vlastnosti.

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)
        }
    }
}

Teď, když je BookList definovaný, lze knihu z předchozího příkladu přidat do seznamu.

$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}

Následující fragment kódu volá statické metody pro třídu.

[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

Příklad 4 – definice třídy se spřažením Runspace a bez

Metoda ShowRunspaceId()[UnsafeClass] hlásí různé ID vlákna, ale stejné ID runspace. Nakonec je stav relace poškozen, což způsobuje chybu, například 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($_)
    }
}

Poznámka:

Tento příklad běží v nekonečné smyčce. Spuštění zastavíte stisknutím klávesy Ctrl+C.

Metoda ShowRunspaceId()[SafeClass] hlásí různé vlákno a ID Runspace.

# 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($_)
    }
}

Poznámka:

Tento příklad běží v nekonečné smyčce. Spuštění zastavíte stisknutím klávesy Ctrl+C.

Vlastnosti třídy

Vlastnosti jsou proměnné deklarované v oboru třídy. Vlastnost může být libovolného předdefinovaný typ nebo instance jiné třídy. Třídy mohou mít nulové nebo více vlastností. Třídy nemají maximální počet vlastností.

Další informace najdete v tématu about_Classes_Properties.

Metody tříd

Metody definují akce, které mohou třídy provádět. Metody mohou přijímat parametry, které určují vstupní data. Metody vždy definují výstupní typ. Pokud metoda nevrací žádný výstup, musí mít výstupní typ Void . Pokud metoda explicitně nedefinuje výstupní typ, je výstupní typ metody Void.

Další informace najdete v tématu about_Classes_Methods.

Konstruktory tříd

Konstruktory umožňují nastavit výchozí hodnoty a ověřit logiku objektu v okamžiku vytvoření instance třídy. Konstruktory mají stejný název jako třída. Konstruktory mohou mít parametry pro inicializaci datových členů nového objektu.

Další informace najdete v tématu about_Classes_Constructors.

Skryté klíčové slovo

Klíčové hidden slovo skryje člena třídy. Člen je stále přístupný pro uživatele a je k dispozici ve všech oborech, ve kterých je objekt k dispozici. Skryté členy jsou v rutině Get-Member skryté a nelze je zobrazit pomocí dokončování tabulátoru nebo IntelliSense mimo definici třídy.

Klíčové hidden slovo se vztahuje pouze na členy třídy, nikoli na samotnou třídu.

Skryté členy třídy jsou:

  • Nezahrnut do výchozího výstupu pro třídu.
  • Součástí seznamu členů třídy vrácených rutinou Get-Member není. Pokud chcete zobrazit skryté členy Get-Member, použijte parametr Force .
  • Nezobrazuje se v dokončování tabulátoru nebo IntelliSense, pokud nedojde k dokončení ve třídě, která definuje skrytý člen.
  • Veřejné členy třídy. Mohou být přístupné, zděděné a změněné. Skrytí člena ho neudělá jako soukromý. Skryje pouze člena, jak je popsáno v předchozích bodech.

Poznámka:

Když skryjete jakékoli přetížení pro metodu, tato metoda je odebrána z IntelliSense, výsledky dokončení a výchozí výstup pro Get-Member. Když skryjete jakýkoli konstruktor, new() možnost se odebere z IntelliSense a výsledků dokončení.

Další informace o klíčovém slově najdete v tématu about_Hidden. Další informace o skrytýchvlastnostech about_Classes_Properties ch Další informace o skrytých metodách najdete v tématu about_Classes_Methods. Další informace o skrytých konstruktorech najdete v tématu about_Classes_Constructors.

Statické klíčové slovo

Klíčové static slovo definuje vlastnost nebo metodu, která existuje ve třídě a nepotřebuje žádnou instanci.

Statická vlastnost je vždy dostupná nezávisle na vytváření instancí třídy. Statická vlastnost se sdílí napříč všemi instancemi třídy. Statická metoda je k dispozici vždy. Všechny statické vlastnosti jsou aktivní pro celé rozsahy relace.

Klíčové static slovo se vztahuje pouze na členy třídy, nikoli na samotnou třídu.

Další informace o statických vlastnostech najdete v tématu about_Classes_Properties. Další informace o statických metodách najdete v tématu about_Classes_Methods. Další informace o statických konstruktorech najdete v tématu about_Classes_Constructors.

Dědičnost ve třídách PowerShellu

Třídu můžete rozšířit vytvořením nové třídy, která je odvozena z existující třídy. Odvozená třída dědí vlastnosti a metody základní třídy. Podle potřeby můžete přidat nebo přepsat členy základní třídy.

PowerShell nepodporuje více dědičnosti. Třídy nemohou dědit přímo z více než jedné třídy.

Třídy mohou také dědit z rozhraní, která definují kontrakt. Třída, která dědí z rozhraní, musí implementovat tento kontrakt. V takovém případě lze třídu použít jako jakoukoli jinou třídu implementujte toto rozhraní.

Další informace o odvození tříd, které dědí ze základní třídy nebo implementují rozhraní, naleznete v tématu about_Classes_Inheritance.

Atribut NoRunspaceAffinity

Runspace je provozní prostředí pro příkazy vyvolané PowerShellem. Toto prostředí zahrnuje příkazy a data, která jsou aktuálně k dispozici, a všechna jazyková omezení, která se aktuálně vztahují.

Ve výchozím nastavení je třída PowerShellu přidružená k prostředí Runspace , kde je vytvořená. Použití třídy PowerShellu není ForEach-Object -Parallel bezpečné. Vyvolání metody ve třídě jsou zařazovány zpět do prostředí Runspace , kde byla vytvořena, což může poškodit stav Runspace nebo způsobit zablokování.

Přidáním atributu NoRunspaceAffinity do definice třídy zajistíte, že třída PowerShellu není přidružená k určitému prostředí runspace. Vyvolání metody, instance i statické, používají Runspace spuštěného vlákna a aktuální stav relace vlákna.

Atribut byl přidán v PowerShellu 7.4.

Obrázek rozdílu v chování tříd s atributem a bez atributu najdete v příkladu NoRunspaceAffinity4.

Export tříd pomocí akcelerátorů typů

Moduly PowerShellu ve výchozím nastavení automaticky nevyexportují třídy a výčty definované v PowerShellu. Vlastní typy nejsou k dispozici mimo modul bez volání using module příkazu.

Pokud ale modul přidá akcelerátory typů, jsou tyto akcelerátory typů okamžitě dostupné v relaci po importu modulu uživateli.

Poznámka:

Přidání akcelerátorů typů do relace používá interní (ne veřejné) rozhraní API. Použití tohoto rozhraní API může způsobit konflikty. Následující vzor vyvolá chybu, pokud při importu modulu již existuje akcelerátor typu se stejným názvem. Odebere také akcelerátory typů, když modul odeberete z relace.

Tento model zajišťuje, že typy jsou k dispozici v relaci. Nemá vliv na IntelliSense ani dokončování při vytváření souboru skriptu ve VS Code. Pokud chcete získat návrhy IntelliSense a dokončování pro vlastní typy v editoru VS Code, musíte do horní části skriptu přidat using module příkaz.

Následující model ukazuje, jak v modulu zaregistrovat třídy PowerShellu a výčty jako akcelerátory typů. Přidejte fragment kódu do modulu kořenového skriptu za definice typu. Ujistěte se, že $ExportableTypes proměnná obsahuje každý z typů, které chcete uživatelům zpřístupnit při importu modulu. Druhý kód nevyžaduje žádné úpravy.

# 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()

Když uživatelé modul naimportují, všechny typy přidané do akcelerátorů typů pro relaci jsou okamžitě dostupné pro IntelliSense a dokončení. Když se modul odebere, jedná se tedy o akcelerátory typů.

Ruční import tříd z modulu PowerShellu

Import-Module#requires a příkaz importuje pouze funkce modulu, aliasy a proměnné, jak je definováno modulem. Třídy se neimportují.

Pokud modul definuje třídy a výčty, ale nepřidá akcelerátory typů pro tyto typy, použijte k jejich importu using module příkaz.

Příkaz using module importuje třídy a výčty z kořenového modulu (ModuleToProcess) modulu skriptu nebo binárního modulu. Neimportuje konzistentně třídy definované v vnořených modulech nebo třídách definovaných ve skriptech, které jsou do kořenového modulu dot-source. Definujte třídy, které chcete zpřístupnit uživatelům mimo modul přímo v kořenovém modulu.

Další informace o using příkazu najdete v tématu about_Using.

Načítání nově změněný kód během vývoje

Při vývoji modulu skriptu je běžné provádět změny kódu a pak načíst novou verzi modulu pomocí Import-Module parametru Force . Opětovné načtení modulu funguje jenom pro změny funkcí v kořenovém modulu. Import-Module nenačítá žádné vnořené moduly. Neexistuje také způsob, jak načíst žádné aktualizované třídy.

Abyste měli jistotu, že používáte nejnovější verzi, musíte spustit novou relaci. Třídy a výčty definované v PowerShellu a importované pomocí using příkazu se nedají uvolnit.

Dalším běžným postupem vývoje je oddělení kódu do různých souborů. Pokud máte funkci v jednom souboru, který používá třídy definované v jiném modulu, měli byste použít using module příkaz k zajištění toho, aby funkce měly potřebné definice tříd.

Typ PSReference není u členů třídy podporován.

Akcelerátor [ref] typů je zkratka pro třídu PSReference . Použití [ref] k přetypování člena třídy se bezobslužně nezdaří. Rozhraní API, která používají [ref] parametry, nelze použít se členy třídy. Třída PSReference byla navržena tak, aby podporovala objekty COM. Objekty COM mají případy, kdy potřebujete předat hodnotu odkazem.

Další informace naleznete v tématu PSReference – třída.

Omezení

Následující seznamy obsahují omezení pro definování tříd PowerShellu a alternativní řešení pro tato omezení, pokud existuje.

Obecná omezení

  • Členové třídy nemůžou jako typ používat PSReference .

    Řešení: Žádné.

  • Třídy PowerShellu nelze v relaci uvolnit ani znovu načíst.

    Alternativní řešení: Spusťte novou relaci.

  • Třídy PowerShellu definované v modulu se neimportují automaticky.

    Alternativní řešení: Přidejte definované typy do seznamu akcelerátorů typů v kořenovém modulu. Díky tomu jsou typy dostupné při importu modulu.

  • Klíčová hidden slova se static vztahují pouze na členy třídy, nikoli na definici třídy.

    Řešení: Žádné.

  • Ve výchozím nastavení nejsou třídy PowerShellu bezpečné používat při paralelním spouštění napříč runspaces. Při vyvolání metod ve třídě PowerShell zařadí vyvolání zpět do Runspace , kde byla třída vytvořena, což může poškodit stav Runspace nebo způsobit zablokování.

    Alternativní řešení: Přidejte NoRunspaceAffinity atribut do deklarace třídy.

Omezení konstruktoru

  • Řetězení konstruktorů není implementováno.

    Alternativní řešení: Definujte skryté Init() metody a volejte je z konstruktorů.

  • Parametry konstruktoru nemohou používat žádné atributy, včetně ověřovacích atributů.

    Alternativní řešení: Přeřaďte parametry v těle konstruktoru pomocí ověřovacího atributu.

  • Parametry konstruktoru nemůžou definovat výchozí hodnoty. Parametry jsou vždy povinné.

    Řešení: Žádné.

  • Pokud je jakékoli přetížení konstruktoru skryté, je každé přetížení konstruktoru považováno za skryté.

    Řešení: Žádné.

Omezení metod

  • Parametry metody nemůžou používat žádné atributy, včetně ověřovacích atributů.

    Alternativní řešení: Přeřaďte parametry v těle metody pomocí ověřovacího atributu nebo definujte metodu ve statickém konstruktoru pomocí rutiny Update-TypeData .

  • Parametry metody nemůžou definovat výchozí hodnoty. Parametry jsou vždy povinné.

    Alternativní řešení: Definujte metodu ve statickém konstruktoru pomocí rutiny Update-TypeData .

  • Metody jsou vždy veřejné, i když jsou skryté. Mohou být přepsány, když je třída zděděna.

    Řešení: Žádné.

  • Pokud je jakékoli přetížení metody skryté, je každé přetížení této metody považováno za skryté.

    Řešení: Žádné.

Omezení vlastností

  • Statické vlastnosti jsou vždy proměnlivé. Třídy PowerShellu nemůžou definovat neměnné statické vlastnosti.

    Řešení: Žádné.

  • Vlastnosti nemohou použít atribut ValidateScript , protože argumenty atributu vlastnosti třídy musí být konstanty.

    Alternativní řešení: Definujte třídu, která dědí z typu ValidateArgumentsAttribute a místo toho tento atribut použijte.

  • Přímo deklarované vlastnosti nemohou definovat vlastní implementace getter a setter.

    Alternativní řešení: Definujte skrytou vlastnost a použijte Update-TypeData k definování viditelné logiky getter a setter.

  • Vlastnosti nemůžou použít atribut Alias . Atribut se vztahuje pouze na parametry, rutiny a funkce.

    Alternativní řešení: Pomocí rutiny Update-TypeData definujte aliasy v konstruktorech tříd.

  • Při převodu třídy PowerShellu ConvertTo-Json na JSON pomocí rutiny obsahuje výstupní JSON všechny skryté vlastnosti a jejich hodnoty.

    Řešení: Žádné

Omezení dědičnosti

  • PowerShell nepodporuje definování rozhraní v kódu skriptu.

    Alternativní řešení: Definujte rozhraní v jazyce C# a odkazujte na sestavení, které definuje rozhraní.

  • Třídy PowerShellu mohou dědit pouze z jedné základní třídy.

    Alternativní řešení: Dědičnost tříd je tranzitivní. Odvozená třída může dědit z jiné odvozené třídy získat vlastnosti a metody základní třídy.

  • Při dědění z obecné třídy nebo rozhraní musí být parametr typu pro obecný již definován. Třída nemůže definovat sama sebe jako parametr typu pro třídu nebo rozhraní.

    Alternativní řešení: Chcete-li odvodit z obecné základní třídy nebo rozhraní, definujte vlastní typ v jiném .psm1 souboru a použijte příkaz using module k načtení typu. Neexistuje žádné alternativní řešení pro použití vlastního typu jako parametru typu při dědění z obecného typu.

Viz také