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 jpg
jpeg
, 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
, oga
e mogg
vengono visualizzati nell'output di GetEnumNames()
, ma l'output di GetEnumValues()
mostra ogg
solo . La stessa cosa accade per jpg
, jpeg
e 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 -band
di 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:
Definisce un'enumerazione denominata
<type>Enum
, ad esempiobyteEnum
. 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 ilMax
valore impostato sul valore massimo per il tipo integrale.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 f
d
x
F
. 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 -band
confronto 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.Bytesbyte
- System.SByteshort
- System.Int16ushort
- System.UInt16int
- System.Int32uint
- System.UInt32long
- System.Int64ulong
- 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 d
X
, 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.