about_Enum

Kurze Beschreibung

Die enum Anweisung deklariert eine Enumeration. Eine Enumeration ist ein eindeutiger Typ, der aus einer Gruppe benannter Bezeichnungen besteht, die als Enumeratorliste bezeichnet werden.

Lange Beschreibung

Mit der enum Anweisung können Sie einen stark typierten Satz von Bezeichnungen erstellen. Sie können diese Enumeration im Code verwenden, ohne die Rechtschreibfehler analysieren oder überprüfen zu müssen.

Enumerationen werden intern als integrale Werttypen mit einem Anfangswert von Null dargestellt. Standardmäßig verwenden PowerShell-Enumerationen System.Int32 ([int]) als zugrunde liegenden Typ. Standardmäßig weist PowerShell die erste Bezeichnung in der Liste dem Wert 0 zu. Standardmäßig weist PowerShell die neu Standard Beschriftungen mit aufeinander folgenden ganzzahligen Zahlen zu.

In der Definition können Sie Beschriftungen mit einem beliebigen ganzzahligen Wert versehen. Beschriftungen ohne zugewiesenen Wert nehmen den nächsten ganzzahligen Wert.

Syntax

Enumerationen verwenden die folgenden Syntaxen:

Syntax der ganzzahligen Enumerationsdefinition

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

Spezifische zugrunde liegende Typdefinitionssyntax

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

Flag-Enumerationsdefinitionssyntax

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

Enumerationszugriffssyntax

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

Beispiele

Beispiel 1 – Minimale Enumeration

Der folgende Codeblock definiert die MarkdownUnorderedListCharacter-Aufzählung mit drei Bezeichnungen. Sie weist keiner Bezeichnung explizite Werte zu.

enum MarkdownUnorderedListCharacter {
    Asterisk
    Dash
    Plus
}

Der nächste Codeblock zeigt, wie sich ganze Zahlen und Zeichenfolgenwerte verhalten, wenn sie in den Enumerationstyp umgewandelt werden.

$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

Umwandlung ganzzahliger Zahlen, die dem Wert einer Aufzählung entsprechen, gibt diese Aufzählung zurück. Umwandlungszeichenfolgen, die mit der Bezeichnung einer Enumeration identisch sind, gibt diese Aufzählung zurück.

Beispiel 2 : Explizite und Synonyme enumerationswerte

Das folgende Beispiel zeigt eine Aufzählung von Objekten, die mit Mediendateien korrelieren. Die Definition weist explizite Werte den zugrunde liegenden Werten von music, picture, . video Beschriftungen, die unmittelbar auf eine explizite Zuordnung folgen, erhalten den nächsten ganzzahligen Wert. Sie können Synonyme erstellen, indem Sie einem anderen Etikett denselben Wert zuweisen. siehe die konstruierten Werte für: ogg, , oga, mogg, oder jpg, oder , jpegmpeg. mpg.

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
}

Die GetEnumNames() Methode gibt die Liste der Bezeichnungen für die Enumeration zurück.

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

Die GetEnumValues() Methode gibt die Liste der Werte für die Enumeration zurück.

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

Hinweis

GetEnumNames() und GetEnumValues() scheinen dieselben Ergebnisse zurückzugeben; eine Liste mit benannten Werten. Intern GetEnumValues() werden die Werte jedoch aufgezählt, dann Werte zu Namen zugeordnet. Lesen Sie die Liste sorgfältig, und Sie werden feststellen, dass ogg, ogaund mogg werden in der Ausgabe von GetEnumNames(), aber die Ausgabe von GetEnumValues() nur angezeigt ogg. Dasselbe geschieht für jpg, jpeg, und mpg, . mpeg Der Name PowerShell gibt für Synonymwerte zurück, ist nicht deterministisch.

Mit der GetEnumName() Methode können Sie einen Namen abrufen, der einem bestimmten Wert zugeordnet ist. Wenn einem Wert mehrere Namen zugeordnet sind, gibt die Methode den ersten definierten Namen zurück.

[MediaTypes].GetEnumName(15)
ogg

Das folgende Beispiel zeigt, wie jeder Name dem Wert zugeordnet wird.

[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

Sie können einen einzelnen Enumerationswert durch die Beschriftung mit der Syntax [<enum-name>]::<label>angeben.

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

Beispiel 3 : Aufzählung als Kennzeichnungen

Der folgende Codeblock erstellt die FileAttributes-Aufzählung als Eine Reihe von Bitkennzeichnungen. Der Wert für jede Beschriftung ist doppelt der Wert der vorherigen Bezeichnung.

[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

Um zu testen, ob ein bestimmtes Flag festgelegt ist, können Sie den Binären Vergleichsoperator -bandverwenden. In diesem Beispiel werden die Attribute "Device" und " Archive " im Wert von $file2.

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

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

Sie können die HasFlag() Methode auch verwenden, um zu testen, ob ein bestimmtes Flag festgelegt ist. In diesem Beispiel werden die Attribute "Device " und "Hidden " im Wert von $file1.

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

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

Beispiel 4 – Enumeration als Parameter

Im folgenden Beispiel definiert die Funktion ConvertTo-LineEndingRegex den InputObject-Parameter mit dem Typ "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

Im Beispiel übergibt die erste Aufrufende Anweisung ConvertTo-LineEndingRegex den Enumerationswert für CR. Die zweite Anweisung übergibt die Zeichenfolge 'CRLF', die in eine LineEnding-Anweisung umgegossen wird. Die dritte Anweisung gibt den Wert für den Parameter 2 an, der der LF Beschriftung zugeordnet ist.

Sie können die Optionen für den Argumentabschluss anzeigen, indem Sie den folgenden Text in die PowerShell-Eingabeaufforderung eingeben:

ConvertTo-LineEndingRegex -InputObject <Tab>

Wenn Sie einen ungültigen Bezeichnungsnamen oder numerischen Wert für den Parameter angeben, löst die Funktion einen Fehler aus.

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

Beispiel 5 : Enumerationen mit bestimmten zugrunde liegenden Typen

Ab PowerShell 6.2 können Sie Enumerationen mit einem bestimmten zugrunde liegenden Typ definieren. Dieses Beispiel zeigt die gültigen zugrunde liegenden Typen für eine Aufzählung.

Der erste Codeblock initialisiert zwei Variablen als Arrays. $EnumTypes ist ein leeres Array, das die dynamisch erstellten Typen enthält. $IntegralTypes ist ein Array, das die gültigen zugrunde liegenden Typen für eine Enumeration enthält.

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

Der nächste Codeblock definiert eine Vorlage, die zum dynamischen Erstellen der Enumerationsdefinitionen verwendet werden soll. Wenn der {0} Formatplatzhalter durch einen integralen Typnamen ersetzt wird, erstellt die Vorlage einen Skriptblock, der:

  1. Definiert eine Aufzählung mit dem Namen <type>Enum, z byteEnum. B. . Die definierte Aufzählung verwendet den angegebenen integralen Typ als zugrunde liegenden Werttyp.

    Die Enumeration wird mit dem Wert definiert, der Min auf den Minimalwert für den integralen Typ festgelegt ist. Er definiert den Wert, der Max auf den Maximalwert für den integralen Typ festgelegt ist.

  2. Gibt den neu definierten Typ zurück.

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

[{0}Enum]
"@

Der nächste Codeblock verwendet die Vorlage, um einen Scriptblock im aktuellen Bereich zu erstellen und aufzurufen. Sie fügt die zurückgegebenen Typdefinitionen in das $EnumTypes Array ein.

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

Der letzte Codeblock durchläuft die Enumerationstypen mithilfe der GetEnumValuesAsUnderlyingType() Methode, um die Werte als zugrunde liegenden Typ auflisten zu können. Die Schleife erstellt ein neues Objekt für jeden Wert, der den Enumerationstyp, den Werttyp, die Beschriftung und den tatsächlichen Wert anzeigt.

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

Enumerationsmethoden

Die folgende Liste enthält nützliche Methoden für Enumerationen in PowerShell und deren Verwendung.

Format

Die Format() statische Methode gibt die formatierte Zeichenfolgenausgabe für einen bestimmten Enumerationstyp, Enumerationswert und Formatzeichenfolge zurück. Die Ausgabe entspricht dem Aufrufen der ToString-Methode für den Wert mit der angegebenen Formatzeichenfolge.

Sie können die statische Methode für den System.Enum-Basisklassentyp oder einen bestimmten Enumerationstyp verwenden.

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

Die gültigen Formatzeichenfolgen sind G oder Dg, oder d, X oder x, und F oder . .f Weitere Informationen finden Sie unter Enumerationsformatzeichenfolgen.

Im folgenden Beispiel werden alle unterstützten Enumerationsformatzeichenfolgen verwendet, um jeden Wert der TaskState-Aufzählung in seine Zeichenfolgendarstellungen zu konvertieren.

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

Die GetEnumName() Spiegelungsmethode gibt den Namen für einen bestimmten Enumerationswert zurück. Der Eingabewert muss ein gültiger zugrunde liegender Typ für eine Enumeration sein, z. B. eine ganze Zahl oder ein Enumerationswert. Wenn einem Wert mehrere Namen zugeordnet sind, gibt die Methode den ersten definierten Namen zurück.

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

Die GetEnumNames() Spiegelungsmethode gibt die Namen für jeden Enumerationswert als Zeichenfolgen zurück. Die Ausgabe enthält Synonyme.

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

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

GetEnumUnderlyingType

Die GetEnumUnderlyingType() Spiegelungsmethode gibt den zugrunde liegenden Typ für die Enumerationswerte zurück.

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

Die GetEnumValues() Spiegelungsmethode gibt jeden definierten Wert für die Enumeration zurück.

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

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

GetEnumValuesAsUnderlyingType

Die GetEnumValuesAsUnderlyingType() Spiegelungsmethode gibt jeden definierten Wert für die Enumeration als zugrunde liegenden Typ zurück.

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

Die HasFlag Instanzmethode bestimmt, ob ein Bit-Flag für einen Flag-Enumerationswert festgelegt ist. Die Verwendung dieser Methode ist kürzer und einfacher zu lesen als bei einem binären Vergleich und einer Äquivalenzüberprüfung.

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

Im folgenden Beispiel wird die ModuleFeatures-Flag-Aufzählung definiert und veranschaulicht, welche Flags der Wert 39 aufweist.

[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

Die IsDefined() statische Methode gibt zurück $true , wenn der Eingabewert für die Enumeration und andernfalls $falsedefiniert ist. Verwenden Sie diese Methode, um zu überprüfen, ob ein Wert für eine Aufzählung gültig ist, ohne ungültige Argumentfehler behandeln zu müssen.

Sie können die statische Methode für den System.Enum-Basisklassentyp oder einen bestimmten Enumerationstyp verwenden.

[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

Die ToString() Instanzmethode gibt die Beschriftung für einen Enumerationswert zurück. Diese Methode ist auch die Standardansicht für die Darstellung eines Enumerationswerts als Ausgabe. Optional können Sie eine Formatzeichenfolge angeben, um zu steuern, wie der Wert angezeigt wird. Weitere Informationen zur Formatierung finden Sie unter Formatierungsaufzählungswerte.

Hinweis

Für Enumerationen, die Synonyme für einen bestimmten Wert definieren, schreiben Sie keinen Code, der von der Ausgabe ToString()abhängt. Die Methode kann einen beliebigen gültigen Namen für den Wert zurückgeben.

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

Im folgenden Beispiel wird die Shade-Aufzählung als Gray Synonym für Grey. Anschließend werden Objekte ausgegeben, die den tatsächlichen Enumerationswert, die Enumeration als Zeichenfolge und die Enumeration als ganze Zahl anzeigen.

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

Enumerationswert-Synonyme

Sie können Enumerationen definieren, die demselben ganzzahligen Wert unterschiedliche Namen zuordnen. Wenn Sie dies tun, werden die Namen, die auf denselben zugrunde liegenden Wert verweisen, Synonyme genannt. Mit Enumerationen mit Synonymen können Benutzer unterschiedliche Namen für denselben Wert angeben.

Wenn Sie eine Aufzählung mit Synonymen definieren, schreiben Sie keinen Code, der von einem Synonymwert abhängt, der in einen bestimmten Namen konvertiert wird. Sie können zuverlässig Code schreiben, der eine Synonymzeichenfolge in den Enumerationswert konvertiert. Wenn Sie mit dem Enumerationswert selbst arbeiten, vergleichen Sie ihn immer als Enumerationswert oder den zugrunde liegenden Typ anstelle einer Zeichenfolge.

Der folgende Codeblock definiert die Shade-Aufzählung mit Grey und Gray als Synonyme.

enum Shade {
    White
    Grey
    Gray = 1
    Black
}

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

Enumerationen als Kennzeichnungen

Eine häufige Verwendung einer Enumeration besteht darin, einen Satz sich gegenseitig ausschließenden Werten darzustellen. Beispielsweise kann eine ArrivalStatus-Instanz den Wert "Early", "OnTime" oder "Late" aufweisen. Es ist nicht sinnvoll, dass der Wert einer ArrivalStatus-Instanz mehr als eine Enumerationskonstante widerspiegelt.

In anderen Fällen kann der Wert eines Enumerationsobjekts jedoch mehrere Enumerationsmember enthalten, und jedes Element stellt ein Bitfeld im Enumerationswert dar. Sie können das FlagsAttribute verwenden, um anzugeben, dass die Enumeration aus Bitfeldern als Flags besteht, die Benutzer kombinieren können.

Damit Enumerationen als Kennzeichnungen ordnungsgemäß funktionieren, müssen Sie den ganzzahligen Wert der einzelnen Bezeichnungen auf eine Potenz von zwei festlegen. Wenn Sie keinen Wert für eine Bezeichnung angeben, legt PowerShell den Wert auf eine höhere als die vorherige Bezeichnung fest.

Sie können Werte für häufig verwendete Kennzeichnungskombinationen definieren, um Benutzern das Gleichzeitige Angeben einer Reihe von Flags zu erleichtern. Der Name für den Wert sollte die kombinierten Namen der Flags sein. Der ganzzahlige Wert sollte die Summe der Flagwerte sein.

Um zu ermitteln, ob ein bestimmtes Flag für einen Wert festgelegt ist, verwenden Sie die HasFlag() Methode für den Wert, oder verwenden Sie den Binären Vergleichsoperator -band.

Ein Beispiel, in dem gezeigt wird, wie Flag-Enumerationen verwendet und überprüft werden, ob ein Flag festgelegt ist, finden Sie unter Beispiel 3.

Enumerationen als Parameter

Sie können Cmdlet-Parameter definieren, die eine Enumeration als Typ verwenden. Wenn Sie eine Enumeration als Typ für einen Parameter angeben, erhalten Benutzer die automatische Fertigstellung und Überprüfung des Werts des Parameters. Der Abschluss des Arguments schlägt die Liste der gültigen Bezeichnungen für die Enumeration vor.

Wenn ein Parameter eine Enumeration als Typ aufweist, können Sie eine der folgenden Elemente angeben:

  • Eine Aufzählung, z. B. [<EnumType>]::<Label>
  • Die Bezeichnung für eine Enumeration als Zeichenfolge
  • Der numerische Wert einer Enumeration

Ein Beispiel mit dem Verhalten eines enumerationstypierten Parameters finden Sie unter Beispiel 4.

Enumerationen mit bestimmten zugrunde liegenden Typen

Ab PowerShell 6.2 können Sie Enumerationen mit einem bestimmten zugrunde liegenden Typ definieren. Wenn Sie eine Aufzählung ohne einen bestimmten zugrunde liegenden Typ definieren, erstellt PowerShell die Aufzählung mit [int] (System.Int32) als zugrunde liegenden Typ.

Der zugrunde liegende Typ für eine Enumeration muss ein integraler numerischer Typ sein. Die folgende Liste enthält die gültigen Typen mit ihrem Kurznamen und dem vollständigen Typnamen:

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

Sie können einen bestimmten zugrunde liegenden Typ für die Aufzählung entweder als Kurz- oder vollständigen Typnamen definieren. Die folgenden Definitionen sind funktional identisch. Nur der name, der für den zugrunde liegenden Typ verwendet wird, unterscheidet sich.

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

Formatieren von Enumerationswerten

Sie können Enumerationswerte in ihre Zeichenfolgendarstellungen konvertieren, indem Sie die statische Format-Methode sowie die Überladungen der ToString-Instanzmethode aufrufen. Sie können eine Formatzeichenfolge verwenden, um die genaue Art und Weise zu steuern, in der ein Enumerationswert als Zeichenfolge dargestellt wird. Weitere Informationen finden Sie unter Enumerationsformatzeichenfolgen.

Im folgenden Beispiel wird jedes der unterstützten Enumerationsformatzeichenfolgen ( oderGg, D oder d, X oder x, und oder fF ) verwendet, um jedes Element der TaskState-Aufzählung in seine Zeichenfolgendarstellungen zu konvertieren.

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

Im folgenden Beispiel werden die Formatzeichenfolgen für Werte einer Flag-Enumeration verwendet.

[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

Beachten Sie, dass für Flags-Enumerationen die G Liste der festgelegten Flags für den durch Kommas getrennten Wert angezeigt und F formatiert wird. Der letzte Wert listet keine Flags auf, 8da es sich nicht um einen gültigen Flagsatz ist. Sie können die Enumerationskennzeichnungen nicht kombinieren, um eine Summe 8 zu erhalten, ohne mindestens ein Flag zu duplizieren.

Definieren von Erweiterungsmethoden mit Update-TypeData

Methoden in der Deklaration für eine Enumeration können nicht definiert werden. Um die Funktionalität einer Enumeration zu erweitern, können Sie das Cmdlet Update-TypeData verwenden, um Member für die Enumeration zu definieren ScriptMethod .

Im folgenden Beispiel wird das Update-TypeData Cmdlet verwendet, um der FileAttributes-Flagenumeration eine GetFlags() Methode hinzuzufügen. Es gibt ein Array der Flags zurück, die für den Wert festgelegt sind.

[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

Exportieren von Enumerationen 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 Enumerationen aus einem PowerShell-Modul

Import-Module und die #requires Anweisung importiert nur die Modulfunktionen, Aliase und Variablen, wie vom Modul definiert. Enumerationen 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. Dies 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 Enumerationen verwendet, die in einem anderen Modul definiert sind, sollten Sie die using module Anweisung verwenden, um sicherzustellen, dass die Funktionen über die erforderlichen Enumerationsdefinitionen verfügen.

Begrenzungen

  • In PowerShell definierte Enumerationswerte können nicht mit Attributen versehen werden. Sie können die Enumerationsdeklaration nur selbst dekorieren, wie beim FlagsAttribute zum Definieren einer Enumeration als Eine Gruppe von Bitkennzeichnungen.

    Abhilfen: Keine

  • Sie können keine Methoden innerhalb von Enumerationsdefinitionen definieren, und PowerShell unterstützt das Definieren von [Erweiterungsmethoden] wie C# nicht.

    Problemumgehung: Verwenden Sie das Cmdlet Update-TypeData , um Member für die Enumeration zu definieren ScriptMethod .