Condividi tramite


about_Enum

Breve descrizione

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

Descrizione lunga

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

Le enumerazioni sono rappresentate internamente come tipi di 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 specifica dell'enumerazione del tipo sottostante

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

Esempio

Esempio 1 - Enumerazione minima

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

enum MarkdownUnorderedListCharacter {
    Asterisk
    Dash
    Plus
}

Il blocco di codice successivo mostra come si comportano sia valori integer che stringa quando viene eseguito 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. Le stringhe di cast uguali all'etichetta di un'enumerazione restituiscono 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 dopo 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, ogamogg, o jpegjpg, 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 di PowerShell restituisce 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 enumerazione tramite la 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 . Questo esempio verifica 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. Questo esempio verifica 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 eseguita il cast in un LineEnding. La terza istruzione specifica il valore 2 per il parametro, che esegue il mapping all'etichetta LF .

È possibile visualizzare le opzioni di completamento degli argomenti 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 in modo dinamico. $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 creare dinamicamente le definizioni di enumerazione. Quando il {0} segnaposto di formato viene sostituito con un nome di tipo integrale, il modello crea uno scriptblock 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 uno scriptblock nell'ambito corrente. Aggiunge le definizioni di tipo restituite nella $EnumTypes matrice.

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

L'ultimo ciclo del blocco di codice 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 enumerazioni in PowerShell e come usarli.

Formato

Il Format() metodo statico restituisce l'output stringa formattato per un determinato tipo di enumerazione, valore di enumerazione e stringa di formato. L'output corrisponde alla chiamata del metodo ToString sul valore con la stringa di formato specificata.

È possibile usare 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 DdXgo o , o xe F o .f Per altre informazioni, vedere Stringhe di formato di enumerazione.

Nell'esempio seguente vengono usate 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 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 metodo di HasFlag 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 visualizzato il flag che contrassegna 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. Usare questo metodo per verificare se un valore è valido per un'enumerazione senza dover gestire errori di argomento non validi.

È possibile usare 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 metodo di ToString() istanza restituisce l'etichetta per un valore di enumerazione. Questo metodo è anche la visualizzazione predefinita per il modo in cui viene visualizzato 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 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 sono denominati 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 sinonimo nel valore di enumerazione. Quando si usa 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 reciprocamente esclusivi. Ad esempio, un'istanza di ArrivalStatus può avere un valore di Early, OnTime o Late. Non ha senso per il valore di un'istanza di ArrivalStatus riflettere più di una costante di enumerazione.

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

Per le enumerazioni come flag per funzionare correttamente, è 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 a quello precedente.

È possibile definire i valori per le combinazioni di flag comunemente usate per semplificare l'impostazione di un set di flag in una sola volta. Il nome del valore deve essere il nome combinato dei flag. Il valore integer deve essere la somma dei valori del flag.

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

Per un esempio che mostra come usare enumerazioni flag e verificare se è impostato un flag, vedere 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 uno qualsiasi di:

  • 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 di enumerazione, vedere 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 il nome completo del tipo. Le definizioni seguenti sono identiche in modo funzionale. Solo il nome utilizzato 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 è rappresentato come stringa. Per altre informazioni, vedere Stringhe di formato di enumerazione.

Nell'esempio seguente vengono usate ognuna delle stringhe di formato di enumerazione supportate (G o XDgdo x) Ff 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 usate 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 flag, le G stringhe di formato e F visualizzano l'elenco di flag 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 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 che gli utenti importano il modulo.

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 sul completamento o su IntelliSense durante la creazione di un file di script in VS Code. Per ottenere suggerimenti per intelliSense e 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 e enumerazioni di PowerShell come acceleratori di tipi in un modulo. Aggiungere il frammento 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 del modulo, gli alias e le variabili, 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 agli utenti esterni al modulo direttamente nel modulo radice.

Per altre informazioni sull'istruzione using , vedere about_Using.

Caricamento del codice appena modificato durante lo sviluppo

Durante lo sviluppo di un modulo script, è comune apportare modifiche al codice e quindi caricare la nuova versione del modulo usando Import-Module il parametro Force . Ciò funziona solo per le modifiche alle funzioni nel modulo radice. Import-Module non ricarica i moduli annidati. Inoltre, non è possibile caricare le 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 caricate.

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, è consigliabile usare l'istruzione using module per assicurarsi che le funzioni dispongano delle definizioni di enumerazione necessarie.

Limitazioni

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