Condividi tramite


about_Enum

Descrizione breve

L'istruzione enum dichiara un'enumerazione. Un'enumerazione è un tipo distinto costituito da un set di etichette denominate denominato elenco enumeratore.

Descrizione lunga

L'istruzione enum consente di creare un set di etichette fortemente tipizzato. È possibile usare tale enumerazione nel codice senza dover analizzare o controllare la presenza di errori ortografici.

Le enumerazioni sono rappresentate internamente come tipi valore integrale con un valore iniziale pari a zero. Per impostazione predefinita, le enumerazioni di PowerShell usano System.Int32 ([int]) come tipo sottostante. Per impostazione predefinita, PowerShell assegna la prima etichetta nell'elenco il valore zero. Per impostazione predefinita, PowerShell assegna le etichette rimanenti con numeri interi consecutivi.

Nella definizione è possibile assegnare etichette a qualsiasi valore intero. Le etichette senza valore assegnato accettano il valore intero successivo.

Sintassi

Le enumerazioni usano le sintassi seguenti:

Sintassi di definizione dell'enumerazione integer

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

Sintassi di definizione dell'enumerazione dei tipi sottostanti specifica

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

Sintassi della definizione dell'enumerazione flag

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

Sintassi di accesso all'enumerazione

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

Esempi

Esempio 1 - Enumerazione minima

Il blocco di codice seguente definisce l'enumerazione MarkdownUnorderedListCharacter con tre etichette. Non assegna valori espliciti ad alcuna etichetta.

enum MarkdownUnorderedListCharacter {
    Asterisk
    Dash
    Plus
}

Il blocco di codice successivo mostra il comportamento dei valori integer e stringa durante il cast al tipo di enumerazione.

$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

Il cast di interi uguali al valore di un'enumerazione restituisce tale enumerazione. Il cast di stringhe uguali all'etichetta di un'enumerazione restituisce tale enumerazione.

Esempio 2 - Valori di enumerazione esplicita e sinonimo

Nell'esempio seguente viene illustrata un'enumerazione di oggetti correlati ai file multimediali. La definizione assegna valori espliciti ai valori sottostanti di music, picture, video. Le etichette immediatamente successive a un'assegnazione esplicita ottengono il valore intero successivo. È possibile creare sinonimi assegnando lo stesso valore a un'altra etichetta; vedere i valori costruiti per: ogg, oga, mogg, o jpgjpeg, o 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
}

Il GetEnumNames() metodo restituisce l'elenco delle etichette per l'enumerazione.

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

Il GetEnumValues() metodo restituisce l'elenco dei valori per l'enumerazione .

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

Nota

GetEnumNames() e GetEnumValues() sembrano restituire gli stessi risultati; un elenco di valori denominati. Tuttavia, internamente, GetEnumValues() enumera i valori, quindi esegue il mapping dei valori in nomi. Leggere attentamente l'elenco e si noterà che ogg, ogae mogg vengono visualizzati nell'output di GetEnumNames(), ma l'output di GetEnumValues() mostra oggsolo . La stessa cosa accade per jpg, jpege mpg, mpeg. Il nome restituito da PowerShell per i valori sinonimi non è deterministico.

È possibile usare il GetEnumName() metodo per ottenere un nome associato a un valore specifico. Se sono presenti più nomi associati a un valore, il metodo restituisce il primo nome definito.

[MediaTypes].GetEnumName(15)
ogg

Nell'esempio seguente viene illustrato come eseguire il mapping di ogni nome al relativo valore.

[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

È possibile specificare un singolo valore di enumerazione in base alla relativa etichetta con la sintassi [<enum-name>]::<label>.

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

Esempio 3 - Enumerazione come flag

Il blocco di codice seguente crea l'enumerazione FileAttributes come set di flag di bit. Il valore per ogni etichetta è doppio del valore dell'etichetta precedente.

[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

Per verificare se è impostato un flag specifico, è possibile usare l'operatore -banddi confronto binario . In questo esempio vengono eseguiti test per gli attributi Device e Archive nel valore di $file2.

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

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

È anche possibile usare il HasFlag() metodo per verificare se è impostato un flag specifico. In questo esempio vengono eseguiti test per gli attributi Device e Hidden nel valore di $file1.

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

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

Esempio 4 - Enumerazione come parametro

Nell'esempio seguente la funzione ConvertTo-LineEndingRegex definisce il parametro InputObject con il tipo 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

Nell'esempio la prima istruzione che chiama ConvertTo-LineEndingRegex passa il valore di enumerazione per CR. La seconda istruzione passa la stringa 'CRLF', che viene eseguito il cast a un oggetto LineEnding. La terza istruzione specifica il valore 2 per il parametro , che esegue il mapping all'etichetta LF .

È possibile visualizzare le opzioni di completamento dell'argomento digitando il testo seguente nel prompt di PowerShell:

ConvertTo-LineEndingRegex -InputObject <Tab>

Quando si specifica un nome di etichetta o un valore numerico non valido per il parametro, la funzione genera un errore.

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

Esempio 5 - Enumerazioni con tipi sottostanti specifici

A partire da PowerShell 6.2, è possibile definire enumerazioni con un tipo sottostante specifico. Questo esempio mostra i tipi sottostanti validi per un'enumerazione.

Il primo blocco di codice inizializza due variabili come matrici. $EnumTypes è una matrice vuota per contenere i tipi creati dinamicamente. $IntegralTypes è una matrice che contiene i tipi sottostanti validi per un'enumerazione.

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

Il blocco di codice successivo definisce un modello da usare per la creazione dinamica delle definizioni di enumerazione. Quando il segnaposto di {0} formato viene sostituito con un nome di tipo integrale, il modello crea un blocco di script che:

  1. Definisce un'enumerazione denominata <type>Enum, ad esempio byteEnum. L'enumerazione definita usa il tipo integrale specificato come tipo di valore sottostante.

    L'enumerazione viene definita con il Min valore impostato sul valore minimo per il tipo integrale. Definisce il Max valore impostato sul valore massimo per il tipo integrale.

  2. Restituisce il tipo appena definito.

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

[{0}Enum]
"@

Il blocco di codice successivo usa il modello per creare e richiamare un blocco di script nell'ambito corrente. Aggiunge le definizioni dei tipi restituite nella $EnumTypes matrice.

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

L'ultimo blocco di codice esegue un ciclo sui tipi di enumerazione, usando il GetEnumValuesAsUnderlyingType() metodo per elencare i valori come tipo sottostante. Il ciclo crea un nuovo oggetto per ogni valore, che mostra il tipo di enumerazione, il tipo di valore, l'etichetta e il valore effettivo.

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

Metodi di enumerazione

L'elenco seguente include metodi utili disponibili per le enumerazioni in PowerShell e come usarli.

Formato

Il Format() metodo statico restituisce l'output della stringa formattata per un tipo di enumerazione, un valore di enumerazione e una stringa di formato specificati. L'output equivale a chiamare il metodo ToString sul valore con la stringa di formato specificata.

È possibile utilizzare il metodo statico nel tipo di classe base System.Enum o in un tipo di enumerazione specifico.

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

Le stringhe di formato valide sono G o g, X D o fdxF . Per altre informazioni, vedere Stringhe di formato di enumerazione.

Nell'esempio seguente vengono utilizzate ognuna delle stringhe di formato di enumerazione supportate per convertire ogni valore dell'enumerazione TaskState nelle relative rappresentazioni di stringa.

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

Il GetEnumName() metodo reflection restituisce il nome per un valore di enumerazione specifico. Il valore di input deve essere un tipo sottostante valido per un'enumerazione, ad esempio un numero intero o un valore di enumerazione. Se sono presenti più nomi associati a un valore, il metodo restituisce il primo nome definito.

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

Il GetEnumNames() metodo reflection restituisce i nomi per ogni valore di enumerazione come stringhe. L'output include sinonimi.

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

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

GetEnumUnderlyingType

Il GetEnumUnderlyingType() metodo reflection restituisce il tipo sottostante per i valori di enumerazione.

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

Il GetEnumValues() metodo reflection restituisce ogni valore definito per l'enumerazione .

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

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

GetEnumValuesAsUnderlyingType

Il GetEnumValuesAsUnderlyingType() metodo reflection restituisce ogni valore definito per l'enumerazione come tipo sottostante.

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

Il HasFlag metodo di istanza determina se un flag di bit è impostato per un valore di enumerazione flag. L'uso di questo metodo è più breve e più semplice da leggere rispetto all'esecuzione di un confronto binario e di un controllo di equivalenza.

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

Nell'esempio seguente viene definita l'enumerazione del flag ModuleFeatures e viene mostrato quale flag ha il valore 39 .

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

$Features = [ModuleFeatures]39

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

IsDefined

Il IsDefined() metodo statico restituisce $true se il valore di input è definito per l'enumerazione e in caso contrario $false. Utilizzare questo metodo per verificare se un valore è valido per un'enumerazione senza dover gestire errori di argomento non validi.

È possibile utilizzare il metodo statico nel tipo di classe base System.Enum o in un tipo di enumerazione specifico.

[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

Il ToString() metodo di istanza restituisce l'etichetta per un valore di enumerazione. Questo metodo è anche la visualizzazione predefinita per la visualizzazione di un valore di enumerazione come output. Facoltativamente, è possibile specificare una stringa di formato per controllare la modalità di visualizzazione del valore. Per altre informazioni sulla formattazione, vedere Formattazione dei valori di enumerazione.

Nota

Per le enumerazioni che definiscono sinonimi per un valore specifico, non scrivere codice che dipende dall'output di ToString(). Il metodo può restituire qualsiasi nome valido per il valore.

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

Nell'esempio seguente viene definita l'enumerazione Shade con Gray come sinonimo di Grey. Restituisce quindi oggetti che mostrano il valore effettivo dell'enumerazione, l'enumerazione come stringa e l'enumerazione come numero intero.

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

Sinonimi dei valori di enumerazione

È possibile definire enumerazioni che assegnano nomi diversi allo stesso valore intero. Quando si esegue questa operazione, i nomi che puntano allo stesso valore sottostante vengono chiamati sinonimi. Le enumerazioni con sinonimi consentono agli utenti di specificare nomi diversi per lo stesso valore.

Quando si definisce un'enumerazione con sinonimi, non scrivere codice che dipende da un valore sinonimo che converte in un nome specifico. È possibile scrivere codice in modo affidabile che converte una stringa di sinonimo nel valore di enumerazione. Quando si lavora con il valore di enumerazione stesso, confrontarlo sempre come valore di enumerazione o il relativo tipo sottostante anziché come stringa.

Il blocco di codice seguente definisce l'enumerazione Shade con Grey e Gray come sinonimi.

enum Shade {
    White
    Grey
    Gray = 1
    Black
}

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

Enumerazioni come flag

Un uso comune di un'enumerazione consiste nel rappresentare un set di valori che si escludono a vicenda. Ad esempio, un'istanza di ArrivalStatus può avere un valore Early, OnTime o Late. Non ha senso che il valore di un'istanza di ArrivalStatus rifletta più di una costante di enumerazione.

In altri casi, tuttavia, il valore di un oggetto di enumerazione può includere più membri di enumerazione e ogni membro rappresenta un campo di bit nel valore di enumerazione. È possibile usare FlagsAttribute per indicare che l'enumerazione è costituita da campi di bit come flag che gli utenti possono combinare.

Per il corretto funzionamento delle enumerazioni come flag, è necessario impostare il valore intero di ogni etichetta su una potenza di due. Se non si specifica un valore per un'etichetta, PowerShell imposta il valore su un valore superiore all'etichetta precedente.

È possibile definire i valori per le combinazioni di flag di uso comune per semplificare l'impostazione di un set di flag contemporaneamente. Il nome del valore deve essere costituito dai nomi combinati dei flag. Il valore intero deve essere la somma dei valori del flag.

Per determinare se un flag specifico è impostato per un valore, utilizzare il HasFlag() metodo sul valore o usare l'operatore di -bandconfronto binario .

Per un esempio che illustra come usare le enumerazioni dei flag e verificare se è impostato un flag, vedere l'esempio 3.

Enumerazioni come parametri

È possibile definire i parametri dei cmdlet che usano un'enumerazione come tipo. Quando si specifica un'enumerazione come tipo per un parametro, gli utenti ottengono il completamento automatico per e la convalida del valore del parametro. Il completamento dell'argomento suggerisce l'elenco di etichette valide per l'enumerazione.

Quando un parametro ha un'enumerazione come tipo, è possibile specificare una delle seguenti:

  • Enumerazione, ad esempio [<EnumType>]::<Label>
  • Etichetta per un'enumerazione come stringa
  • Valore numerico di un'enumerazione

Per un esempio che mostra il comportamento di un parametro tipizzato dall'enumerazione, vedere l'esempio 4.

Enumerazioni con tipi sottostanti specifici

A partire da PowerShell 6.2, è possibile definire enumerazioni con un tipo sottostante specifico. Quando si definisce un'enumerazione senza un tipo sottostante specifico, PowerShell crea l'enumerazione con [int] (System.Int32) come tipo sottostante.

Il tipo sottostante per un'enumerazione deve essere un tipo numerico integrale. L'elenco seguente include i tipi validi con il nome breve e il nome completo del tipo:

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

È possibile definire un tipo sottostante specifico per l'enumerazione come nome breve o nome completo del tipo. Le definizioni seguenti sono identiche a livello funzionale. Solo il nome usato per il tipo sottostante è diverso.

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

Formattazione dei valori di enumerazione

È possibile convertire i valori di enumerazione nelle relative rappresentazioni di stringa chiamando il metodo Format statico, nonché gli overload del metodo ToString dell'istanza. È possibile usare una stringa di formato per controllare il modo preciso in cui un valore di enumerazione viene rappresentato come stringa. Per altre informazioni, vedere Stringhe di formato di enumerazione.

Nell'esempio seguente vengono utilizzate ognuna delle stringhe di formato di enumerazione supportate (G o g, D o dX , o x, e F ) f per convertire ogni membro dell'enumerazione TaskState nelle relative rappresentazioni di stringa.

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

Nell'esempio seguente vengono utilizzate le stringhe di formato per i valori di un'enumerazione flag.

[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

Si noti che per le enumerazioni di flag, le G stringhe di formato e F visualizzano l'elenco di flag di set per il valore delimitato da virgole. L'ultimo valore, 8, non elenca alcun flag perché non è effettivamente un set di flag valido. Non è possibile combinare i flag di enumerazione per ottenere una somma di 8 senza duplicare almeno un flag.

Definizione di metodi di estensione con Update-TypeData

Non è possibile definire metodi nella dichiarazione per un'enumerazione. Per estendere la funzionalità di un'enumerazione, è possibile usare il cmdlet Update-TypeData per definire ScriptMethod i membri per l'enumerazione.

Nell'esempio seguente viene usato il Update-TypeData cmdlet per aggiungere un GetFlags() metodo all'enumerazione del flag FileAttributes . Restituisce una matrice dei flag impostati per il valore .

[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

Esportazione di enumerazioni con acceleratori di tipi

Per impostazione predefinita, i moduli di PowerShell non esportano automaticamente classi ed enumerazioni definite in PowerShell. I tipi personalizzati non sono disponibili all'esterno del modulo senza chiamare un'istruzione using module .

Tuttavia, se un modulo aggiunge acceleratori di tipo, tali acceleratori di tipo sono immediatamente disponibili nella sessione dopo l'importazione del modulo da parte degli utenti.

Nota

L'aggiunta di acceleratori di tipi alla sessione usa un'API interna (non pubblica). L'uso di questa API può causare conflitti. Il modello descritto di seguito genera un errore se esiste già un acceleratore di tipi con lo stesso nome quando si importa il modulo. Rimuove anche gli acceleratori di tipo quando si rimuove il modulo dalla sessione.

Questo modello garantisce che i tipi siano disponibili in una sessione. Non influisce su IntelliSense o sul completamento durante la creazione di un file di script in VS Code. Per ottenere IntelliSense e suggerimenti di completamento per i tipi personalizzati in VS Code, è necessario aggiungere un'istruzione using module all'inizio dello script.

Il modello seguente illustra come registrare classi ed enumerazioni di PowerShell come acceleratori di tipi in un modulo. Aggiungere il frammento di codice al modulo script radice dopo qualsiasi definizione di tipo. Assicurarsi che la $ExportableTypes variabile contenga ognuno dei tipi da rendere disponibili agli utenti quando importano il modulo. L'altro codice non richiede alcuna modifica.

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

Quando gli utenti importano il modulo, tutti i tipi aggiunti agli acceleratori di tipo per la sessione sono immediatamente disponibili per IntelliSense e il completamento. Quando il modulo viene rimosso, quindi sono gli acceleratori di tipo.

Importazione manuale di enumerazioni da un modulo di PowerShell

Import-Module e l'istruzione #requires importa solo le funzioni, gli alias e le variabili del modulo, come definito dal modulo. Le enumerazioni non vengono importate.

Se un modulo definisce classi ed enumerazioni ma non aggiunge acceleratori di tipi per tali tipi, usare un'istruzione using module per importarle.

L'istruzione using module importa classi ed enumerazioni dal modulo radice (ModuleToProcess) di un modulo script o di un modulo binario. Non importa in modo coerente le classi definite in moduli annidati o classi definite negli script con origine punto nel modulo radice. Definire le classi che si desidera essere disponibili per gli utenti esterni al modulo direttamente nel modulo radice.

Per altre informazioni sull'istruzione using , vedere about_Using.

Caricamento di codice appena modificato durante lo sviluppo

Durante lo sviluppo di un modulo di script, è comune apportare modifiche al codice e quindi caricare la nuova versione del modulo usando Import-Module con il parametro Force . Questa operazione funziona solo per le modifiche apportate alle funzioni nel modulo radice. Import-Module non ricarica i moduli annidati. Inoltre, non è possibile caricare classi aggiornate.

Per assicurarsi di eseguire la versione più recente, è necessario avviare una nuova sessione. Le classi e le enumerazioni definite in PowerShell e importate con un'istruzione using non possono essere scaricate.

Un'altra pratica di sviluppo comune consiste nel separare il codice in file diversi. Se si dispone di una funzione in un file che usa enumerazioni definite in un altro modulo, è necessario usare l'istruzione using module per assicurarsi che le funzioni abbiano le definizioni di enumerazione necessarie.

Limiti

  • Non è possibile decorare i valori di enumerazione definiti in PowerShell con attributi. È possibile decorare solo la dichiarazione di enumerazione stessa, come con FlagsAttribute per definire un'enumerazione come set di flag di bit.

    Soluzione alternativa: nessuna

  • Non è possibile definire metodi all'interno delle definizioni di enumerazione e PowerShell non supporta la definizione di [metodi di estensione] come C#.

    Soluzione alternativa: usare il cmdlet Update-TypeData per definire ScriptMethod i membri per l'enumerazione.