about_Enum

Kort beskrivning

-instruktionen enum deklarerar en uppräkning. En uppräkning är en distinkt typ som består av en uppsättning namngivna etiketter som kallas uppräkningslistan.

Lång beskrivning

Med instruktionen enum kan du skapa en starkt typad uppsättning etiketter. Du kan använda uppräkningen i koden utan att behöva parsa eller söka efter stavfel.

Uppräkningar representeras internt som integralvärdetyper med ett startvärde på noll. Som standard använder PowerShell-uppräkningar System.Int32 ([int]) som underliggande typ. Som standard tilldelar PowerShell den första etiketten i listan värdet noll. Som standard tilldelar PowerShell de återstående etiketterna med på varandra följande heltal.

I definitionen kan du ge etiketter valfritt heltalsvärde. Etiketter utan tilldelat värde tar nästa heltalsvärde.

Syntax

Uppräkningar använder följande syntaxer:

Definitionssyntax för heltalsuppräkning

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

Definitionssyntax för specifik underliggande typuppräkning

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

Syntax för flagguppräkningsdefinition

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

Uppräkningsåtkomstsyntax

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

Exempel

Exempel 1 – Minimal uppräkning

Följande kodblock definierar MarkdownUnorderedListCharacter-uppräkningen med tre etiketter. Den tilldelar inte explicita värden till någon etikett.

enum MarkdownUnorderedListCharacter {
    Asterisk
    Dash
    Plus
}

Nästa kodblock visar hur både heltals- och strängvärden beter sig när de skickas till uppräkningstypen.

$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

Gjutnings heltal som är lika med värdet för en uppräkning returnerar den uppräkningen. Gjutningssträngar som är samma som etiketten för en uppräkning returnerar uppräkningen.

Exempel 2 – Explicita och synonymuppräkningsvärden

I följande exempel visas en uppräkning av objekt som korrelerar med mediefiler. Definitionen tilldelar explicita värden till de underliggande värdena musicför , picture, video. Etiketter direkt efter en explicit tilldelning får nästa heltalsvärde. Du kan skapa synonymer genom att tilldela samma värde till en annan etikett. se de konstruerade värdena för: , , , eller jpg, jpegeller 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
}

Metoden GetEnumNames() returnerar listan över etiketterna för uppräkningen.

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

Metoden GetEnumValues() returnerar listan över värdena för uppräkningen.

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

Kommentar

GetEnumNames() och GetEnumValues() verkar returnera samma resultat, en lista med namngivna värden. Internt räknar du dock GetEnumValues() upp värdena och mappar sedan värden till namn. Läs listan noggrant så ser du att ogg, ogaoch mogg visas i utdata från GetEnumNames(), men utdata GetEnumValues() för visar oggbara . Samma sak händer för jpg, jpegoch mpg, mpeg. Namnet PowerShell returnerar för synonymvärden är inte deterministiskt.

Du kan använda GetEnumName() metoden för att hämta ett namn som är associerat med ett visst värde. Om det finns flera namn som är associerade med ett värde returnerar metoden det första definierade namnet.

[MediaTypes].GetEnumName(15)
ogg

I följande exempel visas hur du mappar varje namn till dess värde.

[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

Du kan ange ett enda uppräkningsvärde med dess etikett med syntaxen [<enum-name>]::<label>.

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

Exempel 3 – Uppräkning som flaggor

Följande kodblock skapar Uppräkning av FileAttributes som en uppsättning bitflaggor. Värdet för varje etikett är dubbelt så högt som värdet för den tidigare etiketten.

[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

Om du vill testa om en specifik flagga har angetts kan du använda den binära jämförelseoperatorn -band. I det här exemplet testas attributen Enhet och Arkiv i värdet $file2för .

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

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

Du kan också använda HasFlag() metoden för att testa om en specifik flagga har angetts. I det här exemplet testas attributen Enhet och Dolda i värdet $file1för .

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

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

Exempel 4 – Uppräkning som en parameter

I följande exempel definierar funktionen ConvertTo-LineEndingRegex parametern InputObject med typen 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

I exemplet skickar det första instruktionsanropet ConvertTo-LineEndingRegex uppräkningsvärdet för CR. Den andra instruktionen skickar strängen 'CRLF', som är gjuten till en LineEnding. Den tredje instruktionen anger värdet 2 för parametern, som mappar till LF etiketten.

Du kan se alternativen för att slutföra argumentet genom att skriva följande text i PowerShell-prompten:

ConvertTo-LineEndingRegex -InputObject <Tab>

När du anger ett ogiltigt etikettnamn eller numeriskt värde för parametern genererar funktionen ett fel.

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

Exempel 5 – Uppräkningar med specifika underliggande typer

Från och med PowerShell 6.2 kan du definiera uppräkningar med en specifik underliggande typ. Det här exemplet visar de giltiga underliggande typerna för en uppräkning.

Det första kodblocket initierar två variabler som matriser. $EnumTypes är en tom matris som innehåller de dynamiskt skapade typerna. $IntegralTypes är en matris som innehåller de giltiga underliggande typerna för en uppräkning.

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

Nästa kodblock definierar en mall som ska användas för att dynamiskt skapa uppräkningsdefinitionerna. {0} När formatplatshållaren ersätts med ett namn på en integrerad typ skapar mallen ett skriptblock som:

  1. Definierar en uppräkning med namnet <type>Enum, som byteEnum. Den definierade uppräkningen använder den angivna integraltypen som den underliggande värdetypen.

    Uppräkningen definieras med värdet Min inställt på minimivärdet för integraltypen. Det definierar värdet Max som anges till det maximala värdet för den integrerade typen.

  2. Returnerar den nyligen definierade typen.

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

[{0}Enum]
"@

Nästa kodblock använder mallen för att skapa och anropa en scriptblock i det aktuella omfånget. Den lägger till de returnerade typdefinitionerna i matrisen $EnumTypes .

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

Det sista kodblocket loopar över uppräkningstyperna med hjälp av GetEnumValuesAsUnderlyingType() metoden för att lista värdena som den underliggande typen. Loopen skapar ett nytt objekt för varje värde som visar uppräkningstypen, värdetypen, etiketten och det faktiska värdet.

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

Uppräkningsmetoder

Följande lista innehåller användbara metoder som är tillgängliga för uppräkningar i PowerShell och hur du använder dem.

Format

Den Format() statiska metoden returnerar formaterade strängutdata för en viss uppräkningstyp, uppräkningsvärde och formatsträng. Utdata är samma som att anropa metoden ToString på värdet med den angivna formatsträngen.

Du kan använda den statiska metoden för basklasstypen System.Enum eller en specifik uppräkningstyp.

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

De giltiga formatsträngarna är G eller g, D eller d, X eller xoch F eller f. Mer information finns i Uppräkningsformatsträngar.

I följande exempel används var och en av de uppräkningsformatsträngar som stöds för att konvertera varje värde i TaskState-uppräkningen till dess strängrepresentationer.

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

Reflektionsmetoden GetEnumName() returnerar namnet på ett specifikt uppräkningsvärde. Indatavärdet måste vara en giltig underliggande typ för en uppräkning, till exempel ett heltal eller ett uppräkningsvärde. Om det finns flera namn som är associerade med ett värde returnerar metoden det första definierade namnet.

[<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

Reflektionsmetoden GetEnumNames() returnerar namnen för varje uppräkningsvärde som strängar. Utdata innehåller synonymer.

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

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

GetEnumUnderlyingType

Reflektionsmetoden GetEnumUnderlyingType() returnerar den underliggande typen för uppräkningsvärdena.

[<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

Reflektionsmetoden GetEnumValues() returnerar varje definierat värde för uppräkningen.

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

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

GetEnumValuesAsUnderlyingType

Reflektionsmetoden GetEnumValuesAsUnderlyingType() returnerar varje definierat värde för uppräkningen som den underliggande typen.

[<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

Instansmetoden HasFlag avgör om en bitflagga har angetts för ett flagguppräkningsvärde. Att använda den här metoden är kortare och enklare att läsa än att göra en binär jämförelse och likvärdighetskontroll.

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

I följande exempel definieras flagguppräkning för ModuleFeatures och vilka flaggor värdet 39 har.

[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

Den IsDefined() statiska metoden returnerar $true om indatavärdet har definierats för uppräkningen och i övrigt $false. Använd den här metoden för att kontrollera om ett värde är giltigt för en uppräkning utan att behöva hantera ogiltiga argumentfel.

Du kan använda den statiska metoden för basklasstypen System.Enum eller en specifik uppräkningstyp.

[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

Instansmetoden ToString() returnerar etiketten för ett uppräkningsvärde. Den här metoden är också standardvyn för hur ett uppräkningsvärde visas som utdata. Du kan också ange en formatsträng som styr hur värdet visas. Mer information om formatering finns i Formatera uppräkningsvärden.

Kommentar

Skriv inte kod som är beroende av ToString()utdata för för uppräkningar som definierar synonymer för ett visst värde. Metoden kan returnera valfritt giltigt namn för värdet.

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

I följande exempel definieras uppräkning av skugga med Gray som synonym för Grey. Sedan matas objekt ut som visar det faktiska uppräkningsvärdet, uppräkningen som en sträng och uppräkningen som ett heltal.

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

Synonymer för uppräkningsvärde

Du kan definiera uppräkningar som ger olika namn till samma heltalsvärde. När du gör det kallas namnen som pekar på samma underliggande värde synonymer. Uppräkningar med synonymer gör det möjligt för användare att ange olika namn för samma värde.

När du definierar en uppräkning med synonymer ska du inte skriva kod som är beroende av ett synonymvärde som konverterar till ett specifikt namn. Du kan skriva kod på ett tillförlitligt sätt som konverterar en synonymsträng till uppräkningsvärdet. När du arbetar med själva uppräkningsvärdet ska du alltid jämföra det som ett uppräkningsvärde eller dess underliggande typ i stället för som en sträng.

Följande kodblock definierar shade-uppräkningen med Grey och Gray som synonymer.

enum Shade {
    White
    Grey
    Gray = 1
    Black
}

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

Uppräkningar som flaggor

En vanlig användning av en uppräkning är att representera en uppsättning ömsesidigt uteslutande värden. En ArrivalStatus-instans kan till exempel ha värdet Tidig, OnTime eller Sen. Det är inte meningsfullt att värdet för en ArrivalStatus-instans återspeglar mer än en uppräkningskonstant.

I andra fall kan dock värdet för ett uppräkningsobjekt innehålla flera uppräkningsmedlemmar och varje medlem representerar ett bitfält i uppräkningsvärdet. Du kan använda FlagsAttribute för att ange att uppräkningen består av bitfält som flaggor som användarna kan kombinera.

För att uppräkningar som flaggor ska fungera korrekt måste du ställa in varje etiketts heltalsvärde på två. Om du inte anger något värde för en etikett anger PowerShell värdet till ett som är högre än den tidigare etiketten.

Du kan definiera värden för flaggkombinationer som används ofta för att göra det enklare för användare att ange en uppsättning flaggor samtidigt. Namnet på värdet ska vara de kombinerade namnen på flaggorna. Heltalsvärdet ska vara summan av flaggvärdena.

Om du vill avgöra om en specifik flagga har angetts för ett värde använder du HasFlag() metoden för värdet eller använder den binära jämförelseoperatorn -band.

Ett exempel som visar hur du använder flagguppräkningar och kontrollerar om en flagga har angetts finns i Exempel 3.

Uppräkningar som parametrar

Du kan definiera cmdlet-parametrar som använder en uppräkning som typ. När du anger en uppräkning som typ för en parameter får användarna automatiskt slutförande för och validering av parameterns värde. Argumentets slutförande föreslår en lista över giltiga etiketter för uppräkningen.

När en parameter har en uppräkning som sin typ kan du ange något av följande:

  • En uppräkning, till exempel [<EnumType>]::<Label>
  • Etiketten för en uppräkning som en sträng
  • Det numeriska värdet för en uppräkning

Ett exempel som visar beteendet för en uppräkningstypad parameter finns i Exempel 4.

Uppräkningar med specifika underliggande typer

Från och med PowerShell 6.2 kan du definiera uppräkningar med en specifik underliggande typ. När du definierar en uppräkning utan en specifik underliggande typ skapar PowerShell uppräkningen med [int] (System.Int32) som underliggande typ.

Den underliggande typen för en uppräkning måste vara en integrerad numerisk typ. Följande lista innehåller giltiga typer med deras korta namn och fullständiga typnamn:

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

Du kan definiera en specifik underliggande typ för uppräkning som antingen det korta namnet eller det fullständiga typnamnet. Följande definitioner är funktionellt identiska. Endast namnet som används för den underliggande typen är annorlunda.

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

Formatera uppräkningsvärden

Du kan konvertera uppräkningsvärden till deras strängrepresentationer genom att anropa metoden statiskt format , samt överlagringarna av instansmetoden ToString . Du kan använda en formatsträng för att styra exakt hur ett uppräkningsvärde representeras som en sträng. Mer information finns i Uppräkningsformatsträngar.

I följande exempel används var och en av de uppräkningsformatsträngar som stöds (G eller g, D eller d, X eller x, och F eller f ) för att konvertera varje medlem i TaskState-uppräkningen till dess strängrepresentationer.

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

I följande exempel används formatsträngarna för värden för en flagguppräkning.

[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

Observera att för uppräkningar G av flaggor visar och F formatsträngarna listan med angivna flaggor för det värde som avgränsas med kommatecken. Det sista värdet, 8, visar inga flaggor eftersom det faktiskt inte är en giltig flagguppsättning. Du kan inte kombinera uppräkningsflaggor för att få en summa utan 8 att duplicera minst en flagga.

Definiera tilläggsmetoder med Update-TypeData

Du kan inte definiera metoder i deklarationen för en uppräkning. Om du vill utöka funktionen för en uppräkning kan du använda cmdleten Update-TypeData för att definiera ScriptMethod medlemmar för uppräkningen.

I följande exempel används cmdleten Update-TypeData för att lägga till en GetFlags() metod i fileAttributes-flagguppräkningen . Den returnerar en matris med flaggorna som angetts för värdet.

[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

Exportera uppräkningar med typacceleratorer

Som standard exporterar PowerShell-moduler inte automatiskt klasser och uppräkningar som definierats i PowerShell. De anpassade typerna är inte tillgängliga utanför modulen utan att anropa en using module instruktion.

Men om en modul lägger till typacceleratorer är dessa typacceleratorer omedelbart tillgängliga i sessionen efter att användarna har importerat modulen.

Kommentar

När du lägger till typacceleratorer i sessionen används ett internt (inte offentligt) API. Om du använder det här API:et kan det orsaka konflikter. Mönstret nedan genererar ett fel om det redan finns en typaccelerator med samma namn när du importerar modulen. Den tar också bort typacceleratorerna när du tar bort modulen från sessionen.

Det här mönstret säkerställer att typerna är tillgängliga i en session. Det påverkar inte IntelliSense eller slutförande när du redigerar en skriptfil i VS Code. För att få IntelliSense- och slutförandeförslag för anpassade typer i VS Code måste du lägga till en using module instruktion överst i skriptet.

Följande mönster visar hur du kan registrera PowerShell-klasser och uppräkningar som typacceleratorer i en modul. Lägg till kodfragmentet i rotskriptmodulen efter alla typdefinitioner. Kontrollera att variabeln $ExportableTypes innehåller var och en av de typer som du vill göra tillgängliga för användare när de importerar modulen. Den andra koden kräver ingen redigering.

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

När användarna importerar modulen är alla typer som läggs till i typacceleratorerna för sessionen omedelbart tillgängliga för IntelliSense och slutförande. När modulen tas bort, så är även typacceleratorerna.

Importera uppräkningar manuellt från en PowerShell-modul

Import-Module och -instruktionen #requires importerar endast modulfunktioner, alias och variabler enligt modulens definition. Uppräkningar importeras inte.

Om en modul definierar klasser och uppräkningar men inte lägger till typacceleratorer för dessa typer använder du en using module instruktion för att importera dem.

Instruktionen using module importerar klasser och uppräkningar från rotmodulen (ModuleToProcess) i en skriptmodul eller binär modul. Den importerar inte konsekvent klasser som definierats i kapslade moduler eller klasser som definierats i skript som är punktbaserade i rotmodulen. Definiera klasser som du vill ska vara tillgängliga för användare utanför modulen direkt i rotmodulen.

Mer information om -instruktionen finns i using about_Using.

Läser in nyligen ändrad kod under utveckling

Under utvecklingen av en skriptmodul är det vanligt att göra ändringar i koden och sedan läsa in den nya versionen av modulen med hjälp Import-Module av parametern Force . Detta fungerar endast för ändringar av funktioner i rotmodulen. Import-Module läser inte in några kapslade moduler igen. Det finns inte heller något sätt att läsa in några uppdaterade klasser.

För att säkerställa att du kör den senaste versionen måste du starta en ny session. Klasser och uppräkningar som definierats i PowerShell och importerats med en using instruktion kan inte tas bort.

En annan vanlig utvecklingspraxis är att dela upp koden i olika filer. Om du har en funktion i en fil som använder uppräkningar som definierats i en annan modul bör du använda -instruktionen using module för att säkerställa att funktionerna har de uppräkningsdefinitioner som behövs.

Begränsningar

  • Du kan inte dekorera uppräkningsvärden som definierats i PowerShell med attribut. Du kan bara dekorera själva uppräkningsdeklarationen, som med FlagsAttribute för att definiera en uppräkning som en uppsättning bitflaggor.

    Lösning: Inga

  • Du kan inte definiera metoder i uppräkningsdefinitioner och PowerShell har inte stöd för att definiera [tilläggsmetoder] som C#.

    Lösning: Använd cmdleten Update-TypeData för att definiera ScriptMethod medlemmar för uppräkningen.