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
, oga
mogg
, o jpeg
jpg
, 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 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 -band
di 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:
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 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 D
d
X
g
o o , o x
e 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 -band
di 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.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 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 X
D
g
d
o x
) 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 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.