about_Enum

Krátký popis

Příkaz enum deklaruje výčet. Výčet je jedinečný typ, který se skládá ze sady pojmenovaných popisků označovaných jako seznam enumerátoru.

Dlouhý popis

Příkaz enum umožňuje vytvořit sadu popisků silného typu. Tento výčet můžete použít v kódu, aniž byste museli analyzovat nebo kontrolovat pravopisné chyby.

Výčty jsou interně reprezentovány jako celočíselné typy hodnot s počáteční hodnotou nuly. Ve výchozím nastavení používají výčty PowerShellu jako základní typ System.Int32 ([int]). PowerShell ve výchozím nastavení přiřadí první popisek v seznamu nula. PowerShell ve výchozím nastavení přiřadí zbývající popisky s po sobě jdoucími celými čísly.

V definici můžete popisky zadat libovolnou celočíselnou hodnotu. Popisky bez přiřazené hodnoty přebírají další celočíselnou hodnotu.

Syntaxe

Výčty používají následující syntaxe:

Syntaxe definice výčtu celého čísla

[[<attribute>]...] enum <enum-name> {
    <label> [= <int-value>]
    ...
}

Syntaxe definice výčtu konkrétního základního typu

[[<attribute>]...] enum <enum-name> : <underlying-type-name> {
    <label> [= <int-value>]
    ...
}

Syntaxe definice výčtu příznaku

[[<attribute>]...] [Flag()] enum <enum-name>[ : <underlying-type-name>] {
    <label 0> [= 1]
    <label 1> [= 2]
    <label 2> [= 4]
    <label 3> [= 8]
    ...
    ...
}

Syntaxe přístupu k výčtu

[<enum-name>]::<label>

Příklady

Příklad 1 – minimální výčet

Následující blok kódu definuje MarkdownUnorderedListCharacter výčet se třemi popisky. Nepřiřazuje explicitní hodnoty žádnému popisku.

enum MarkdownUnorderedListCharacter {
    Asterisk
    Dash
    Plus
}

Další blok kódu ukazuje, jak se při přetypování na typ výčtu chovají celočíselné i řetězcové hodnoty.

$ValuesToConvert = @(0, 'Asterisk', 1, 'Dash', 2, 'Plus')
foreach ($Value in $ValuesToConvert) {
    [MarkdownUnorderedListCharacter]$EnumValue = $Value

    [pscustomobject]@{
        AssignedValue = $Value
        Enumeration   = $EnumValue
        AreEqual      = $Value -eq $EnumValue
    }
}
AssignedValue Enumeration AreEqual
------------- ----------- --------
            0    Asterisk     True
     Asterisk    Asterisk     True
            1        Dash     True
         Dash        Dash     True
            2        Plus     True
         Plus        Plus     True

Přetypování celých čísel, která jsou rovna hodnotě výčtu, vrátí tento výčet. Přetypování řetězců, které jsou stejné jako popisek výčtu, vrátí tento výčet.

Příklad 2 – explicitní hodnoty výčtu a výčtu synonym

Následující příklad ukazuje výčet objektů, které korelují s multimediálními soubory. Definice přiřadí explicitní hodnoty podkladovým hodnotám music, , picturevideo. Popisky bezprostředně za explicitním přiřazením získají další celočíselnou hodnotu. Synonyma můžete vytvořit přiřazením stejné hodnoty jinému popisku; viz vytvořené hodnoty pro: , , , nebo jpg, jpegnebo , nebo mpg, mpeg. moggogaogg

enum MediaTypes {
    unknown
    music   = 10
    mp3
    aac
    ogg     = 15
    oga     = 15
    mogg    = 15
    picture = 20
    jpg
    jpeg    = 21
    png
    video   = 40
    mpg
    mpeg    = 41
    avi
    m4v
}

Metoda GetEnumNames() vrátí seznam popisků výčtu.

[MediaTypes].GetEnumNames()
unknown
music
mp3
aac
ogg
oga
mogg
picture
jpg
jpeg
png
video
mpg
mpeg
avi
m4v

Metoda GetEnumValues() vrátí seznam hodnot pro výčet.

[MediaTypes].GetEnumValues()
unknown
music
mp3
aac
ogg
ogg
ogg
picture
jpg
jpg
png
video
mpg
mpg
avi
m4v

Poznámka:

GetEnumNames() a GetEnumValues() zdá se, že vrací stejné výsledky; seznam pojmenovaných hodnot. Interně GetEnumValues() však hodnoty vyčíslí a pak mapuje hodnoty na názvy. Seznam si pečlivě přečtěte a všimnete si, že ogg, ogaa mogg zobrazí se ve výstupu GetEnumNames(), ale výstup GetEnumValues() pouze ukazuje ogg. Totéž se děje pro jpg, jpega mpg, , mpeg. Název PowerShellu pro hodnoty synonym není deterministický.

Metodu GetEnumName() můžete použít k získání názvu přidruženého ke konkrétní hodnotě. Pokud existuje více názvů přidružených k hodnotě, vrátí metoda první definovaný název.

[MediaTypes].GetEnumName(15)
ogg

Následující příklad ukazuje, jak namapovat každý název na jeho hodnotu.

[MediaTypes].GetEnumNames() | ForEach-Object {
  [pscustomobject]@{
    Name = $_
    Value = [int]([MediaTypes]::$_)
  }
}
Name    Value
----    -----
unknown     0
music      10
mp3        11
aac        12
ogg        15
oga        15
mogg       15
picture    20
jpg        21
jpeg       21
png        22
video      40
mpg        41
mpeg       41
avi        42
m4v        43

Pomocí syntaxe [<enum-name>]::<label>můžete zadat jednu hodnotu výčtu.

[MediaTypes]::png
[MediaTypes]::png -eq 22
png
True

Příklad 3 – výčet jako příznaky

Následující blok kódu vytvoří výčet FileAttributes jako sadu bitových příznaků. Hodnota každého popisku je dvojitá hodnota předchozího popisku.

[Flags()] enum FileAttributes {
    Archive    = 1
    Compressed = 2
    Device     = 4
    Directory  = 8
    Encrypted  = 16
    Hidden     = 32
}

[FileAttributes]$file1 =  [FileAttributes]::Archive
[FileAttributes]$file1 += [FileAttributes]::Compressed
[FileAttributes]$file1 += [FileAttributes]::Device
"file1 attributes are: $file1"

[FileAttributes]$file2 = [FileAttributes]28 ## => 16 + 8 + 4
"file2 attributes are: $file2"
file1 attributes are: Archive, Compressed, Device
file2 attributes are: Device, Directory, Encrypted

Chcete-li otestovat, zda je nastaven určitý příznak, můžete použít binární relační operátor -band. Tento příklad testuje atributy Device a Archive v hodnotě $file2.

PS > ($file2 -band [FileAttributes]::Device) -eq [FileAttributes]::Device
True

PS > ($file2 -band [FileAttributes]::Archive) -eq [FileAttributes]::Archive
False

Metodu HasFlag() můžete použít také k otestování, jestli je nastavený konkrétní příznak. Tento příklad testuje atributy Device a Hidden v hodnotě $file1.

PS > $file1.HasFlag([FileAttributes]::Device)
True

PS > $file1.HasFlag([FileAttributes]::Hidden)
False

Příklad 4 – výčet jako parametr

V následujícím příkladu funkce ConvertTo-LineEndingRegex definuje InputObject parametr s typem EndOfLine.

enum EndOfLine {
    CR   = 1
    LF   = 2
    CRLF = 3
}

function ConvertTo-LineEndingRegex {
    [CmdletBinding()]
    param (
        [Parameter(ValueFromPipeline)]
        [EndOfLine[]]$InputObject
    )

    process {
        switch ($InputObject) {
            CR   {  '\r'  }
            LF   {  '\n'  }
            CRLF { '\r\n' }
        }
    }
}

[EndOfLine]::CR | ConvertTo-LineEndingRegex

'CRLF' | ConvertTo-LineEndingRegex

ConvertTo-LineEndingRegex 2
\r

\r\n

\n

V příkladu první příkaz volání ConvertTo-LineEndingRegex předá hodnotu výčtu pro CR. Druhý příkaz předá řetězec 'CRLF', který se přetypuje na LineEnding. Třetí příkaz určuje hodnotu 2 parametru, který se mapuje na LF popisek.

Možnosti dokončování argumentů můžete zobrazit zadáním následujícího textu do příkazového řádku PowerShellu:

ConvertTo-LineEndingRegex -InputObject <Tab>

Když pro parametr zadáte neplatný název popisku nebo číselnou hodnotu, funkce vyvolá chybu.

ConvertTo-LineEndingRegex -InputObject 0
ConvertTo-LineEndingRegex: Cannot process argument transformation on
parameter 'InputObject'. Cannot convert value "0" to type "EndOfLine" due
to enumeration values that are not valid. Specify one of the following
enumeration values and try again. The possible enumeration values are
"CR,LF,CRLF".

Příklad 5 – výčet s konkrétními podkladovými typy

Počínaje PowerShellem 6.2 můžete definovat výčty s konkrétním základním typem. Tento příklad ukazuje platné základní typy pro výčet.

První blok kódu inicializuje dvě proměnné jako pole. $EnumTypes je prázdné pole, které bude obsahovat dynamicky vytvořené typy. $IntegralTypes je pole, které obsahuje platné základní typy pro výčet.

$EnumTypes     = @()
$IntegralTypes = @(
    'byte', 'sbyte', 'short', 'ushort', 'int', 'uint', 'long', 'ulong'
)

Další blok kódu definuje šablonu, která se má použít pro dynamické vytváření definic výčtu. {0} Když se zástupný symbol formátu nahradí celočíselným názvem, šablona vytvoří blok skriptu, který:

  1. Definuje výčet s názvem <type>Enum, například byteEnum. Definovaný výčet používá zadaný celočíselný typ jako typ podkladové hodnoty.

    Výčet je definován s Min hodnotou nastavenou na minimální hodnotu celočíselného typu. Definuje hodnotu nastavenou Max na maximální hodnotu celočíselného typu.

  2. Vrátí nově definovaný typ.

$DefinitionTemplate = @"
enum {0}Enum : {0} {{
    Min = [{0}]::MinValue
    Max = [{0}]::MaxValue
}}

[{0}Enum]
"@

Další blok kódu použije šablonu k vytvoření a vyvolání bloku skriptu v aktuálním oboru. Přidá do pole definice vráceného $EnumTypes typu.

foreach ($IntegralType in $IntegralTypes) {
    $Definition  = $DefinitionTemplate -f $IntegralType
    $ScriptBlock = [scriptblock]::Create($Definition)
    $EnumTypes  += . $ScriptBlock
}

Poslední blokovací smyčka kódu přes typy výčtu pomocí GetEnumValuesAsUnderlyingType() metody k výpisu hodnot jako základního typu. Smyčka vytvoří nový objekt pro každou hodnotu, který zobrazuje typ výčtu, typ hodnoty, popisek a skutečnou hodnotu.

foreach ($EnumType in $EnumTypes) {
    $EnumType.GetEnumValuesAsUnderlyingType() | ForEach-Object {
        [pscustomobject]@{
            EnumType  = $EnumType.FullName
            ValueType = $_.GetType().FullName
            Label     = $EnumType.GetEnumName($_)
            Value     = $_
        }
    }
}
EnumType   ValueType     Label                Value
--------   ---------     -----                -----
byteEnum   System.Byte   Min                      0
byteEnum   System.Byte   Max                    255
sbyteEnum  System.SByte  Max                    127
sbyteEnum  System.SByte  Min                   -128
shortEnum  System.Int16  Max                  32767
shortEnum  System.Int16  Min                 -32768
ushortEnum System.UInt16 Min                      0
ushortEnum System.UInt16 Max                  65535
intEnum    System.Int32  Max             2147483647
intEnum    System.Int32  Min            -2147483648
uintEnum   System.UInt32 Min                      0
uintEnum   System.UInt32 Max             4294967295
longEnum   System.Int64  Max    9223372036854775807
longEnum   System.Int64  Min   -9223372036854775808
ulongEnum  System.UInt64 Min                      0
ulongEnum  System.UInt64 Max   18446744073709551615

Metody výčtu

Následující seznam obsahuje užitečné metody, které jsou k dispozici pro výčet v PowerShellu a jejich použití.

Formát

Format() Statická metoda vrátí výstup formátovaného řetězce pro daný typ výčtu, hodnotu výčtu a formátovací řetězec. Výstup je stejný jako volání ToString metoda na hodnotu se zadaným formátovacím řetězcem.

Statickou metodu můžete použít pro typ základní třídy System.Enum nebo konkrétní typ výčtu.

[System.Enum]::format([<enum-name>], <value>, <format-string>)
[<enum-name>]::format([<enum-name>], <value>, <format-string>)

Platné formátovací řetězce jsou G nebo g, D nebo dX , nebo x, a F nebo .f Další informace naleznete v tématu Výčtové formátovací řetězce.

Následující příklad používá každý z podporovaných řetězců formátu výčtu k převodu každé hodnoty výčtu TaskState na jeho řetězcové reprezentace.

enum TaskState {
    ToDo
    Doing
    Done
}

# String format template for the statements
$Statement = "[System.Enum]::Format([TaskState], {0}, '{1}')"

foreach ($Format in @('G', 'D', 'X', 'F')) {
    $StatementToDo  = $Statement -f 0, $Format
    $StatementDoing = $Statement -f "([TaskState]'Doing')", $Format
    $StatementDone  = $Statement -f '[TaskState]::Done', $Format
    $FormattedToDo  = [System.Enum]::Format(
      [TaskState], 0, $Format
    )
    $FormattedDoing = [System.Enum]::Format(
        [TaskState], ([TaskState]'Doing'), $Format
    )
    $FormattedDone  = [System.Enum]::Format(
      [TaskState], [TaskState]::Done, $Format
    )

    "{0,-62} => {1}" -f $StatementToDo,  $FormattedToDo
    "{0,-62} => {1}" -f $StatementDoing, $FormattedDoing
    "{0,-62} => {1}" -f $StatementDone,  $FormattedDone
}
[System.Enum]::Format([TaskState], 0, 'G')                     => ToDo
[System.Enum]::Format([TaskState], ([TaskState]'Doing'), 'G')  => Doing
[System.Enum]::Format([TaskState], [TaskState]::Done, 'G')     => Done
[System.Enum]::Format([TaskState], 0, 'D')                     => 0
[System.Enum]::Format([TaskState], ([TaskState]'Doing'), 'D')  => 1
[System.Enum]::Format([TaskState], [TaskState]::Done, 'D')     => 2
[System.Enum]::Format([TaskState], 0, 'X')                     => 00000000
[System.Enum]::Format([TaskState], ([TaskState]'Doing'), 'X')  => 00000001
[System.Enum]::Format([TaskState], [TaskState]::Done, 'X')     => 00000002
[System.Enum]::Format([TaskState], 0, 'F')                     => ToDo
[System.Enum]::Format([TaskState], ([TaskState]'Doing'), 'F')  => Doing
[System.Enum]::Format([TaskState], [TaskState]::Done, 'F')     => Done

GetEnumName

Metoda GetEnumName() reflexe vrátí název pro konkrétní hodnotu výčtu. Vstupní hodnota musí být platným základním typem pro výčet, například celé číslo nebo hodnotu výčtu. Pokud existuje více názvů přidružených k hodnotě, vrátí metoda první definovaný název.

[<enum-name>].GetEnumName(<value>)
enum GateState {
    Unknown
    Open
    Opening
    Closing
    Closed
}

foreach ($Value in 0..4) {
    [pscustomobject]@{
      IntegerValue = $Value
      EnumName     = [GateState].GetEnumName($Value)
    }
}
IntegerValue EnumName
------------ --------
           0 Unknown
           1 Open
           2 Opening
           3 Closing
           4 Closed

GetEnumNames

Metoda GetEnumNames() reflexe vrátí názvy pro každou hodnotu výčtu jako řetězce. Výstup obsahuje synonyma.

[<enum-name>].GetEnumNames()
enum Season {
    Unknown
    Spring
    Summer
    Autumn
    Winter
    Fall   = 3
}

[Season].GetEnumNames()
Unknown
Spring
Summer
Fall
Autumn
Winter

GetEnumUnderlyingType

Metoda GetEnumUnderlyingType() reflexe vrátí základní typ pro hodnoty výčtu.

[<enum-name>].GetEnumUnderlyingType()
enum IntBasedEnum {
    Zero
    One
    Two
}
enum ShortBasedEnum : short {
    Zero
    One
    Two
}

foreach ($EnumType in @([IntBasedEnum], [ShortBasedEnum])) {
    [pscustomobject]@{
        EnumType = $EnumType
        ValueType = $EnumType.GetEnumUnderlyingType()
    }
}
EnumType       ValueType
--------       ---------
IntBasedEnum   System.Int32
ShortBasedEnum System.Int16

GetEnumValues

Metoda GetEnumValues() reflexe vrátí každou definovanou hodnotu pro výčet.

[<enum-name>].GetEnumValues()
enum Season {
    Unknown
    Spring
    Summer
    Autumn
    Winter
    Fall   = 3
}

[Season].GetEnumValues()
Unknown
Spring
Summer
Fall
Fall
Winter

GetEnumValuesAsUnderlyingType

Metoda GetEnumValuesAsUnderlyingType() reflexe vrátí každou definovanou hodnotu pro výčet jako základní typ.

[<enum-name>].GetEnumValuesAsUnderlyingType()
enum IntBasedEnum {
    Zero
    One
    Two
}
enum ShortBasedEnum : short {
    Zero
    One
    Two
}

foreach ($EnumType in @([IntBasedEnum], [ShortBasedEnum])) {
    [pscustomobject]@{
        EnumType = $EnumType
        ValueType = $EnumType.GetEnumValuesAsUnderlyingType()[0].GetType()
    }
}
EnumType       ValueType
--------       ---------
IntBasedEnum   System.Int32
ShortBasedEnum System.Int16

HasFlag

Metoda HasFlag instance určuje, zda je bit příznak nastaven pro hodnotu výčtu příznaku. Použití této metody je kratší a čitelnější než provádění binárního porovnání a kontroly ekvivalence.

<enum-value>.HasFlag(<enum-flag-value>)

Následující příklad definuje výčet příznaku ModuleFeatures a ukazuje, které příznaky má hodnota 39 .

[Flags()] enum ModuleFeatures {
    Commands  = 1
    Classes   = 2
    Enums     = 4
    Types     = 8
    Formats   = 16
    Variables = 32
}

$Features = [ModuleFeatures]39

foreach ($Feature in [ModuleFeatures].GetEnumValues()) {
    "Has flag {0,-12}: {1}" -f "'$Feature'", ($Features.HasFlag($Feature))
}
Has flag 'Commands'  : True
Has flag 'Classes'   : True
Has flag 'Enums'     : True
Has flag 'Types'     : False
Has flag 'Formats'   : False
Has flag 'Variables' : True

Isdefined

IsDefined() Statická metoda vrátí$true, pokud je vstupní hodnota definována pro výčet a jinak $false. Tato metoda slouží ke kontrole, zda je hodnota platná pro výčet, aniž by bylo nutné zpracovat chyby neplatných argumentů.

Statickou metodu můžete použít pro typ základní třídy System.Enum nebo konkrétní typ výčtu.

[System.Enum]::IsDefined([<enum-name>], <value>)
[<enum-name>]::IsDefined([<enum-name>], <value>)
enum Season {
    Unknown
    Spring
    Summer
    Autumn
    Winter
    Fall   = 3
}

foreach ($Value in 0..5) {
    $IsValid   = [Season]::IsDefined([Season], $Value)
    $EnumValue = if ($IsValid) { [Season]$Value }

    [pscustomobject] @{
        InputValue = $Value
        IsValid    = $IsValid
        EnumValue  = $EnumValue
    }
}
InputValue IsValid EnumValue
---------- ------- ---------
         0    True   Unknown
         1    True    Spring
         2    True    Summer
         3    True      Fall
         4    True    Winter
         5   False

ToString

Metoda ToString() instance vrátí popisek pro hodnotu výčtu. Tato metoda je také výchozím zobrazením, jak se hodnota výčtu zobrazuje jako výstup. Volitelně můžete zadat formátovací řetězec, který určuje způsob zobrazení hodnoty. Další informace o formátování naleznete v tématu Formátování výčtu hodnot.

Poznámka:

Pro výčty, které definují synonyma pro konkrétní hodnotu, nezapisujte kód, který závisí na výstupu ToString(). Metoda může vrátit libovolný platný název hodnoty.

<enum-value>.ToString([<format-string>])

Následující příklad definuje shade výčtu jako Gray synonymum pro Grey. Pak vypíše objekty, které zobrazují skutečnou hodnotu výčtu, výčt jako řetězec a výčet jako celé číslo.

enum Shade {
    White
    Grey
    Gray = 1
    Black
}

[Shade].GetEnumValues() | Foreach-Object -Process {
    [pscustomobject]@{
        EnumValue    = $_
        StringValue  = $_.ToString()
        IntegerValue = [int]$_
    }
}
numValue StringValue IntegerValue
--------- ----------- ------------
    White White                  0
     Grey Grey                   1
     Grey Grey                   1
    Black Black                  2

Synonyma hodnot výčtu

Můžete definovat výčty, které dávají různým názvům stejnou celočíselnou hodnotu. Když to uděláte, názvy, které odkazují na stejnou podkladovou hodnotu, se nazývají synonyma. Výčty se synonymy umožňují uživatelům zadat různé názvy pro stejnou hodnotu.

Při definování výčtu se synonymy nezapisujte kód, který závisí na hodnotě synonym, která se převádí na konkrétní název. Můžete spolehlivě napsat kód, který převede řetězec synonyma na hodnotu výčtu. Při práci se samotnou hodnotou výčtu ji vždy porovnejte jako hodnotu výčtu nebo jeho základního typu, nikoli jako řetězec.

Následující blok kódu definuje výčet Shade s synonymy Grey a Gray jako synonyma.

enum Shade {
    White
    Grey
    Gray = 1
    Black
}

[Shade]'Grey' -eq [Shade]::Gray
[Shade]::Grey -eq 1
[Shade]'Gray' -eq 1
True
True
True

Výčty jako příznaky

Jedním z běžných použití výčtu je reprezentace sady vzájemně se vylučujících hodnot. Například instance ArrivalStatus může mít hodnotu Early, OnTime nebo Late. Nemá smysl pro hodnotu instance ArrivalStatus odrážet více než jednu výčtovou konstantu.

V jiných případech však hodnota objektu výčtu může obsahovat více členů výčtu a každý člen představuje bitové pole v hodnotě výčtu. Příznak FlagsAttribute můžete použít k označení, že výčet se skládá z bitových polí jako příznaků, které mohou uživatelé kombinovat.

Aby výčty fungovaly správně jako příznaky, musíte nastavit celočíselnou hodnotu každého popisku na mocninu dvou. Pokud nezadáte hodnotu popisku, PowerShell nastaví hodnotu na jednu vyšší než předchozí popisek.

Můžete definovat hodnoty pro běžně používané kombinace příznaků, které uživatelům usnadní zadání sady příznaků najednou. Název hodnoty by měl být sloučené názvy příznaků. Celočíselná hodnota by měla být součet hodnot příznaku.

Chcete-li zjistit, zda je pro hodnotu nastaven určitý příznak, použijte HasFlag() metodu pro hodnotu nebo použijte binární relační operátor -band.

Ukázku ukazující, jak používat výčty příznaků a zkontrolovat, jestli je nastavený příznak, najdete v příkladu 3.

Výčty jako parametry

Můžete definovat parametry rutiny, které jako typ používají výčt. Když jako typ parametru zadáte výčet, uživatelé získají automatické dokončování a ověření hodnoty parametru. Dokončení argumentu navrhuje seznam platných popisků výčtu.

Pokud má parametr výčt jako jeho typ, můžete zadat některou z těchto možností:

  • Výčet, například [<EnumType>]::<Label>
  • Popisek výčtu jako řetězec
  • Číselná hodnota výčtu

Příklad znázorňující chování parametru typu výčtu naleznete v příkladu 4.

Výčty s konkrétními podkladovými typy

Počínaje PowerShellem 6.2 můžete definovat výčty s konkrétním základním typem. Když definujete výčet bez konkrétního základního typu, PowerShell vytvoří výčet s [int] (System.Int32) jako základním typem.

Základní typ výčtu musí být celočíselný číselný typ. Následující seznam obsahuje platné typy s krátkým názvem a úplným názvem:

  • byte - System.Byte
  • sbyte - System.SByte
  • short - System.Int16
  • ushort - System.UInt16
  • int - System.Int32
  • uint - System.UInt32
  • long - System.Int64
  • ulong - System.UInt64

Můžete definovat konkrétní základní typ výčtu buď jako krátký název, nebo úplný název typu. Následující definice jsou funkčně identické. Liší se pouze název použitý pro podkladový typ.

enum LongValueEnum : long {
    Zero
    One
    Two
}
enum LongValueEnum : System.Int64 {
    Zero
    One
    Two
}

Formátování hodnot výčtu

Hodnoty výčtu můžete převést na jejich řetězcové reprezentace voláním static Format metoda, stejně jako přetížení instance ToString metoda. Řetězec formátu můžete použít k řízení přesného způsobu, jakým je hodnota výčtu reprezentována jako řetězec. Další informace naleznete v tématu Výčtové formátovací řetězce.

Následující příklad používá každý z podporovaných řetězců formátu výčtu (G nebo g, D nebo d, X nebo x, a F nebo f ) k převodu každého člena výčtu TaskState na jeho řetězcové reprezentace.

enum TaskState {
    ToDo
    Doing
    Done
}

[TaskState].GetEnumValues() | ForEach-Object {
    [pscustomobject]@{
        "ToString('G')" = $_.ToString('G')
        "ToString('D')" = $_.ToString('D')
        "ToString('X')" = $_.ToString('X')
        "ToString('F')" = $_.ToString('F')
    }
}
ToString('G') ToString('D') ToString('X') ToString('F')
------------- ------------- ------------- -------------
ToDo          0             00000000      ToDo
Doing         1             00000001      Doing
Done          2             00000002      Done

Následující příklad používá formátovací řetězce pro hodnoty výčtu příznaku.

[Flags()] enum FlagEnum {
    A = 1
    B = 2
    C = 4
}

$FlagValues = @(
    [FlagEnum]::A                                 # 1
    [FlagEnum]::B                                 # 2
    [FlagEnum]::A + [FlagEnum]::B                 # 3
    [FlagEnum]::C                                 # 4
    [FlagEnum]::C + [FlagEnum]::A                 # 5
    [FlagEnum]::C + [FlagEnum]::B                 # 6
    [FlagEnum]::C + [FlagEnum]::A + [FlagEnum]::B # 7
    [FlagEnum]::C + [FlagEnum]::C                 # 8
)

foreach ($Value in $FlagValues) {
    [pscustomobject]@{
        "ToString('G')" = $Value.ToString('G')
        "ToString('D')" = $Value.ToString('D')
        "ToString('X')" = $Value.ToString('X')
        "ToString('F')" = $Value.ToString('F')
    }
}
ToString('G') ToString('D') ToString('X') ToString('F')
------------- ------------- ------------- -------------
A             1             00000001      A
B             2             00000002      B
A, B          3             00000003      A, B
C             4             00000004      C
A, C          5             00000005      A, C
B, C          6             00000006      B, C
A, B, C       7             00000007      A, B, C
8             8             00000008      8

Všimněte si, že pro výčty G příznaků zobrazují řetězce a F formátovací řetězce seznam příznaků sady pro hodnotu oddělenou čárkami. Poslední hodnota neobsahuje žádné příznaky, 8protože ve skutečnosti není platná sada příznaků. Pokud chcete získat součet bez 8 duplikování alespoň jednoho příznaku, nemůžete kombinovat příznaky výčtu.

Definování rozšiřujících metod pomocí Update-TypeData

V deklaraci pro výčet nelze definovat metody. Chcete-li rozšířit funkce výčtu, můžete pomocí rutiny Update-TypeData definovat ScriptMethod členy pro výčet.

Následující příklad používá rutinu Update-TypeDataGetFlags() k přidání metody do výčtu příznaku FileAttributes . Vrátí pole příznaků nastavených pro hodnotu.

[Flags()] enum FileAttributes {
    Archive    = 1
    Compressed = 2
    Device     = 4
    Directory  = 8
    Encrypted  = 16
    Hidden     = 32
}

$MemberDefinition = @{
    TypeName   = 'FileAttributes'
    MemberName = 'GetFlags'
    MemberType = 'ScriptMethod'
    Value      = {
        foreach ($Flag in $this.GetType().GetEnumValues()) {
          if ($this.HasFlag($Flag)) { $Flag }
        }
    }
}

Update-TypeData @MemberDefinition

$File = [FileAttributes]28

$File.GetFlags()
Device
Directory
Encrypted

Export výčtů 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 výčtů z modulu PowerShellu

Import-Module#requires a příkaz importuje pouze funkce modulu, aliasy a proměnné, jak je definováno modulem. Výčty 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 . To 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á výčty definované v jiném modulu, měli byste pomocí using module příkazu zajistit, aby funkce měly potřebné definice výčtu.

Omezení

  • Hodnoty výčtu definované v PowerShellu nemůžete ozdobit atributy. Můžete pouze ozdobit samotnou deklaraci výčtu, stejně jako u FlagsAttribute pro definování výčtu jako sady bitových příznaků.

    Řešení: Žádné

  • V definicích výčtu nemůžete definovat metody a PowerShell nepodporuje definování [rozšiřujících metod] jako C#.

    Alternativní řešení: K definování ScriptMethod členů výčtu použijte rutinu Update-TypeData.