Freigeben über


about_Enum

Kurze Beschreibung

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

Lange Beschreibung

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

Enumerationen werden intern als integrale Werttypen mit einem Anfangswert von 0 (null) dargestellt. Standardmäßig verwenden PowerShell-Enumerationen System.Int32 ([int]) als zugrunde liegenden Typ. Standardmäßig weist PowerShell der ersten Bezeichnung in der Liste den Wert 0 zu. Standardmäßig weist PowerShell die verbleibenden Bezeichnungen mit aufeinanderfolgenden ganzen Zahlen zu.

In der Definition können Sie Bezeichnungen einen beliebigen ganzzahligen Wert zugeben. Bezeichnungen ohne zugewiesenen Wert übernehmen den nächsten ganzzahligen Wert.

Syntax

Enumerationen verwenden die folgenden Syntaxen:

Syntax der Integer-Enumerationsdefinition

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

Syntax der spezifischen zugrunde liegenden Typenumerationsdefinition

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

Syntax der Flagenumerationsdefinition

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

Syntax des Enumerationszugriffs

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

Beispiele

Beispiel 1: Minimale Enumeration

Der folgende Codeblock definiert die MarkdownUnorderedListCharacter-Enumeration mit drei Bezeichnungen. Es werden keiner Bezeichnung explizite Werte zugewiesen.

enum MarkdownUnorderedListCharacter {
    Asterisk
    Dash
    Plus
}

Der nächste Codeblock zeigt, wie sich sowohl ganzzahlige Werte als auch 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

Beim Umwandeln von ganzen Zahlen, die dem Wert einer Enumeration entsprechen, wird diese Enumeration zurückgegeben. Das Umwandeln von Zeichenfolgen, die mit der Bezeichnung einer Enumeration identisch sind, gibt diese Enumeration zurück.

Beispiel 2: Explizite Und Synonymenumerationswerte

Das folgende Beispiel zeigt eine Enumeration von -Objekten, die mit Mediendateien korrelieren. Die Definition weist den zugrunde liegenden Werten von music, , pictureexplizite videoWerte zu. Bezeichnungen, die unmittelbar auf eine explizite Zuweisung folgen, erhalten den nächsten ganzzahligen Wert. Sie können Synonyme erstellen, indem Sie denselben Wert einer anderen Bezeichnung zuweisen. Siehe die konstruierten Werte für: ogg, oga, moggoder jpg, jpegoder mpg, . mpeg

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 die gleichen Ergebnisse zurückzugeben; eine Liste mit benannten Werten. Listet die Werte jedoch intern auf, GetEnumValues() und ordnet die Werte dann namen zu. Lesen Sie die Liste sorgfältig, und Sie werden feststellen, dass ogg, ogaund mogg in der Ausgabe von GetEnumNames()angezeigt werden, aber die Ausgabe von GetEnumValues() zeigt oggnur an. Dasselbe gilt für jpg, jpegund mpg, mpeg. Der Name, den PowerShell für Synonymwerte zurückgibt, ist nicht deterministisch.

Sie können die GetEnumName() -Methode verwenden, um einen Namen abzurufen, 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 seinem 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 anhand seiner Bezeichnung mit der Syntax [<enum-name>]::<label>angeben.

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

Beispiel 3: Enumeration als Flags

Der folgende Codeblock erstellt die FileAttributes-Enumeration als Satz von Bitflags. Der Wert für jede Bezeichnung ist doppelt so viel wie 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 $file2getestet.

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 wird auf die Attribute Device und Hidden im Wert von $file1getestet.

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 Anweisung, die aufruft ConvertTo-LineEndingRegex , den Enumerationswert für CR. Die zweite Anweisung übergibt die Zeichenfolge 'CRLF', die in ein LineEnding umgewandelt wird. Die dritte Anweisung gibt den Wert 2 für den Parameter an, der der LF Bezeichnung zugeordnet ist.

Sie können die Optionen für die Argumentvervollständigen anzeigen, indem Sie den folgenden Text in Ihre 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 Enumeration.

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 Scriptblock, der Folgendes bewirkt:

  1. Definiert eine Enumeration mit dem Namen <type>Enum, z. B byteEnum. . Die definierte Enumeration 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 Skriptblock im aktuellen Bereich zu erstellen und aufzurufen. Die zurückgegebenen Typdefinitionen werden dem $EnumTypes Array hinzugefügt.

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

Der letzte Codeblock überläuft die Enumerationstypen, wobei die GetEnumValuesAsUnderlyingType() -Methode verwendet wird, um die Werte als zugrunde liegenden Typ aufzulisten. Die Schleife erstellt für jeden Wert ein neues Objekt, das den Enumerationstyp, den Werttyp, die Bezeichnung 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, die für Enumerationen in PowerShell verfügbar sind und wie sie verwendet werden.

Format

Die Format() statische Methode gibt die formatierte Zeichenfolgenausgabe für einen bestimmten Enumerationstyp, Enumerationswert und eine formatierte Zeichenfolge 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 g, D oder d, X oder x, und F oder f. Weitere Informationen finden Sie unter Enumerationsformatzeichenfolgen.

Im folgenden Beispiel werden die einzelnen unterstützten Enumerationsformatzeichenfolgen verwendet, um jeden Wert der TaskState-Enumeration in die zugehörigen 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() Reflektionsmethode 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() Reflektionsmethode 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() Reflektionsmethode 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() Reflektionsmethode 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() Reflektionsmethode 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 instance-Methode bestimmt, ob ein Bitflag für einen Flagaufzählungswert festgelegt ist. Die Verwendung dieser Methode ist kürzer und einfacher zu lesen als ein binärer Vergleich und eine Gleichwertigkeitsprüfung.

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

Das folgende Beispiel definiert die ModuleFeatures-Flagaufzählung und zeigt, 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 Enumeration gültig ist, ohne dass ungültige Argumentfehler behandelt werden 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() instance-Methode gibt die Bezeichnung 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 von 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-Enumeration mit Gray als Synonym für Greydefiniert. Anschließend werden Objekte ausgegeben, die den tatsächlichen Enumerationswert, die Enumeration als Zeichenfolge und die Enume 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 geben. Wenn Sie dies tun, werden die Namen, die auf denselben zugrunde liegenden Wert verweisen, Synonyme genannt. Enumerationen mit Synonymen ermöglichen es Benutzern, unterschiedliche Namen für denselben Wert anzugeben.

Wenn Sie eine Enumeration mit Synonymen definieren, schreiben Sie keinen Code, der davon abhängt, dass ein Synonymwert 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 als zugrunde liegender Typ statt als Zeichenfolge.

Der folgende Codeblock definiert die Shade-Enumeration 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 Flags

Eine häufige Verwendung einer Enumeration besteht darin, einen Satz von Werten darzustellen, die sich gegenseitig ausschließen. Ein ArrivalStatus-instance kann z. B. den Wert Early, OnTime oder Late aufweisen. Es ist nicht sinnvoll, dass der Wert eines ArrivalStatus-instance 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 flagsAttribute verwenden, um anzugeben, dass die Enumeration aus Bitfeldern als Flags besteht, die Benutzer kombinieren können.

Damit Enumerationen als Flags ordnungsgemäß funktionieren, müssen Sie den ganzzahligen Wert jeder Bezeichnung auf eine Leistung von zwei festlegen. Wenn Sie keinen Wert für eine Bezeichnung angeben, legt PowerShell den Wert auf einen höher als die vorherige Bezeichnung fest.

Sie können Werte für häufig verwendete Flagkombinationen definieren, um Benutzern die gleichzeitige Angabe 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 bestimmen, ob ein bestimmtes Flag für einen Wert festgelegt ist, verwenden Sie die HasFlag() -Methode für den Wert oder den binären Vergleichsoperator -band.

Ein Beispiel für die Verwendung von Flagaufzählungen und die Überprüfung, ob ein Flag festgelegt ist, finden Sie unter Beispiel 3.

Enumerationen als Parameter

Sie können Cmdletparameter definieren, die eine Enumeration als Typ verwenden. Wenn Sie eine Enumeration als Typ für einen Parameter angeben, erhalten Benutzer eine automatische Vervollständigung und Überprüfung des Werts des Parameters. Die Argumentvervollständigen schlägt die Liste der gültigen Bezeichnungen für die Enumeration vor.

Wenn ein Parameter über eine Enumeration als Typ verfügt, können Sie folgendes angeben:

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

Ein Beispiel, das das Verhalten eines enumerationstypisierten Parameters zeigt, 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 Enumeration ohne einen bestimmten zugrunde liegenden Typ definieren, erstellt PowerShell die Enumeration 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 Enumeration entweder als Kurzname oder als vollständigen Typnamen definieren. Die folgenden Definitionen sind funktional identisch. Nur der name, der für den zugrunde liegenden Typ verwendet wird, ist unterschiedlich.

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 instance ToString-Methode aufrufen. Sie können eine Formatzeichenfolge verwenden, um die genaue Darstellung eines Enumerationswerts als Zeichenfolge zu steuern. Weitere Informationen finden Sie unter Enumerationsformatzeichenfolgen.

Im folgenden Beispiel werden jede der unterstützten Enumerationsformatzeichenfolgen (G oder g, D oder d, X oder x, und F oder f ) verwendet, um jedes Element der TaskState-Enumeration in die zugehörigen 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 Flagaufzählung 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 Formatzeichenfolgen und F die Liste der festgelegten Flags für den durch Kommas getrennten Wert anzeigen. Der letzte Wert, 8, listet keine Flags auf, da es sich nicht um einen gültigen Flagsatz handelt. Sie können die Enumerationsflags nicht kombinieren, um eine Summe von 8 zu erhalten, ohne mindestens ein Flag zu duplizieren.

Definieren von Erweiterungsmethoden mit Update-TypeData

Sie können keine Methoden in der Deklaration für eine Enumeration definieren. 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-Flagaufzählung 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 Typbeschleunigungen

Standardmäßig exportieren PowerShell-Module 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 Typbeschleunigungen hinzufügt, sind diese Typbeschleunigungen sofort in der Sitzung verfügbar, nachdem Benutzer das Modul importiert haben.

Hinweis

Das Hinzufügen von Typbeschleunigungen zur Sitzung verwendet eine interne (nicht öffentliche) API. Die Verwendung dieser API kann Zu Konflikten führen. Das unten beschriebene Muster löst einen Fehler aus, wenn beim Importieren des Moduls bereits eine Typbeschleunigung mit demselben Namen vorhanden ist. Außerdem werden die Typbeschleunigungen 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 die Vervollständigung aus. Um IntelliSense- und Vervollständigungsvorschläge für benutzerdefinierte Typen in VS Code abzurufen, müssen Sie am Anfang des Skripts 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 dem Stammskriptmodul nach allen Typdefinitionen hinzu. Stellen Sie sicher, dass die $ExportableTypes Variable alle 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 Typbeschleunigungen für die Sitzung hinzugefügt wurden, sofort für IntelliSense und die Vervollständigung verfügbar. Wenn das Modul entfernt wird, sind dies auch die Typbeschleunigungen.

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. Klassen, die in geschachtelten Modulen definiert sind, oder klassen, die in Skripts definiert sind, die aus Punktquellen stammen, werden nicht konsistent in das Stammmodul 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

Während der Entwicklung eines Skriptmoduls ist es üblich, Änderungen am Code vorzunehmen und dann die neue Version des Moduls mit Import-Module dem Force-Parameter 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 werden, können nicht entladen werden.

Eine weitere gängige Entwicklungspraxis besteht darin, Ihren Code in verschiedene Dateien zu unterteilen. 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.

Einschränkungen

  • Sie können in PowerShell definierte Enumerationswerte nicht mit Attributen versehen. Sie können nur die Enumerationsdeklaration selbst wie mit flagsAttribute zum Definieren einer Enumeration als Satz von Bitflags versehen.

    Problemumgehung: Keine

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

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