about_Enum
Krátký popis
Příkaz enum
deklaruje výčet. Výčet je jedinečný typ, který se skládá ze sady pojmenovaných popisků označovaných jako seznam enumerátoru.
Dlouhý popis
Příkaz enum
umožňuje vytvořit sadu popisků silného typu. Tento výčet můžete použít v kódu, aniž byste museli analyzovat nebo kontrolovat pravopisné chyby.
Výčty jsou interně reprezentovány jako celočíselné typy hodnot s počáteční hodnotou nuly. Ve výchozím nastavení používají výčty PowerShellu jako základní typ System.Int32 ([int]
). PowerShell ve výchozím nastavení přiřadí první popisek v seznamu nula. PowerShell ve výchozím nastavení přiřadí zbývající popisky s po sobě jdoucími celými čísly.
V definici můžete popisky zadat libovolnou celočíselnou hodnotu. Popisky bez přiřazené hodnoty přebírají další celočíselnou hodnotu.
Syntaxe
Výčty používají následující syntaxe:
Syntaxe definice výčtu celého čísla
[[<attribute>]...] enum <enum-name> {
<label> [= <int-value>]
...
}
Syntaxe definice výčtu konkrétního základního typu
[[<attribute>]...] enum <enum-name> : <underlying-type-name> {
<label> [= <int-value>]
...
}
Syntaxe definice výčtu příznaku
[[<attribute>]...] [Flag()] enum <enum-name>[ : <underlying-type-name>] {
<label 0> [= 1]
<label 1> [= 2]
<label 2> [= 4]
<label 3> [= 8]
...
...
}
Syntaxe přístupu k výčtu
[<enum-name>]::<label>
Příklady
Příklad 1 – minimální výčet
Následující blok kódu definuje MarkdownUnorderedListCharacter výčet se třemi popisky. Nepřiřazuje explicitní hodnoty žádnému popisku.
enum MarkdownUnorderedListCharacter {
Asterisk
Dash
Plus
}
Další blok kódu ukazuje, jak se při přetypování na typ výčtu chovají celočíselné i řetězcové hodnoty.
$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
Přetypování celých čísel, která jsou rovna hodnotě výčtu, vrátí tento výčet. Přetypování řetězců, které jsou stejné jako popisek výčtu, vrátí tento výčet.
Příklad 2 – explicitní hodnoty výčtu a výčtu synonym
Následující příklad ukazuje výčet objektů, které korelují s multimediálními soubory. Definice přiřadí explicitní hodnoty podkladovým hodnotám music
, , picture
video
. Popisky bezprostředně za explicitním přiřazením získají další celočíselnou hodnotu. Synonyma můžete vytvořit přiřazením stejné hodnoty jinému popisku; viz vytvořené hodnoty pro: , , , nebo jpg
, jpeg
nebo , nebo mpg
, mpeg
. mogg
oga
ogg
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
}
Metoda GetEnumNames()
vrátí seznam popisků výčtu.
[MediaTypes].GetEnumNames()
unknown
music
mp3
aac
ogg
oga
mogg
picture
jpg
jpeg
png
video
mpg
mpeg
avi
m4v
Metoda GetEnumValues()
vrátí seznam hodnot pro výčet.
[MediaTypes].GetEnumValues()
unknown
music
mp3
aac
ogg
ogg
ogg
picture
jpg
jpg
png
video
mpg
mpg
avi
m4v
Poznámka:
GetEnumNames()
a GetEnumValues()
zdá se, že vrací stejné výsledky; seznam pojmenovaných hodnot. Interně GetEnumValues()
však hodnoty vyčíslí a pak mapuje hodnoty na názvy. Seznam si pečlivě přečtěte a všimnete si, že ogg
, oga
a mogg
zobrazí se ve výstupu GetEnumNames()
, ale výstup GetEnumValues()
pouze ukazuje ogg
. Totéž se děje pro jpg
, jpeg
a mpg
, , mpeg
. Název PowerShellu pro hodnoty synonym není deterministický.
Metodu GetEnumName()
můžete použít k získání názvu přidruženého ke konkrétní hodnotě. Pokud existuje více názvů přidružených k hodnotě, vrátí metoda první definovaný název.
[MediaTypes].GetEnumName(15)
ogg
Následující příklad ukazuje, jak namapovat každý název na jeho hodnotu.
[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
Pomocí syntaxe [<enum-name>]::<label>
můžete zadat jednu hodnotu výčtu.
[MediaTypes]::png
[MediaTypes]::png -eq 22
png
True
Příklad 3 – výčet jako příznaky
Následující blok kódu vytvoří výčet FileAttributes jako sadu bitových příznaků. Hodnota každého popisku je dvojitá hodnota předchozího popisku.
[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
Chcete-li otestovat, zda je nastaven určitý příznak, můžete použít binární relační operátor -band
. Tento příklad testuje atributy Device a Archive v hodnotě $file2
.
PS > ($file2 -band [FileAttributes]::Device) -eq [FileAttributes]::Device
True
PS > ($file2 -band [FileAttributes]::Archive) -eq [FileAttributes]::Archive
False
Metodu HasFlag()
můžete použít také k otestování, jestli je nastavený konkrétní příznak.
Tento příklad testuje atributy Device a Hidden v hodnotě $file1
.
PS > $file1.HasFlag([FileAttributes]::Device)
True
PS > $file1.HasFlag([FileAttributes]::Hidden)
False
Příklad 4 – výčet jako parametr
V následujícím příkladu funkce ConvertTo-LineEndingRegex
definuje InputObject parametr s typem 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
V příkladu první příkaz volání ConvertTo-LineEndingRegex
předá hodnotu výčtu pro CR
. Druhý příkaz předá řetězec 'CRLF'
, který se přetypuje na LineEnding. Třetí příkaz určuje hodnotu 2
parametru, který se mapuje na LF
popisek.
Možnosti dokončování argumentů můžete zobrazit zadáním následujícího textu do příkazového řádku PowerShellu:
ConvertTo-LineEndingRegex -InputObject <Tab>
Když pro parametr zadáte neplatný název popisku nebo číselnou hodnotu, funkce vyvolá chybu.
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".
Příklad 5 – výčet s konkrétními podkladovými typy
Počínaje PowerShellem 6.2 můžete definovat výčty s konkrétním základním typem. Tento příklad ukazuje platné základní typy pro výčet.
První blok kódu inicializuje dvě proměnné jako pole. $EnumTypes
je prázdné pole, které bude obsahovat dynamicky vytvořené typy. $IntegralTypes
je pole, které obsahuje platné základní typy pro výčet.
$EnumTypes = @()
$IntegralTypes = @(
'byte', 'sbyte', 'short', 'ushort', 'int', 'uint', 'long', 'ulong'
)
Další blok kódu definuje šablonu, která se má použít pro dynamické vytváření definic výčtu. {0}
Když se zástupný symbol formátu nahradí celočíselným názvem, šablona vytvoří blok skriptu, který:
Definuje výčet s názvem
<type>Enum
, napříkladbyteEnum
. Definovaný výčet používá zadaný celočíselný typ jako typ podkladové hodnoty.Výčet je definován s
Min
hodnotou nastavenou na minimální hodnotu celočíselného typu. Definuje hodnotu nastavenouMax
na maximální hodnotu celočíselného typu.Vrátí nově definovaný typ.
$DefinitionTemplate = @"
enum {0}Enum : {0} {{
Min = [{0}]::MinValue
Max = [{0}]::MaxValue
}}
[{0}Enum]
"@
Další blok kódu použije šablonu k vytvoření a vyvolání bloku skriptu v aktuálním oboru. Přidá do pole definice vráceného $EnumTypes
typu.
foreach ($IntegralType in $IntegralTypes) {
$Definition = $DefinitionTemplate -f $IntegralType
$ScriptBlock = [scriptblock]::Create($Definition)
$EnumTypes += . $ScriptBlock
}
Poslední blokovací smyčka kódu přes typy výčtu pomocí GetEnumValuesAsUnderlyingType()
metody k výpisu hodnot jako základního typu. Smyčka vytvoří nový objekt pro každou hodnotu, který zobrazuje typ výčtu, typ hodnoty, popisek a skutečnou hodnotu.
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
Metody výčtu
Následující seznam obsahuje užitečné metody, které jsou k dispozici pro výčet v PowerShellu a jejich použití.
Formát
Format()
Statická metoda vrátí výstup formátovaného řetězce pro daný typ výčtu, hodnotu výčtu a formátovací řetězec. Výstup je stejný jako volání ToString metoda na hodnotu se zadaným formátovacím řetězcem.
Statickou metodu můžete použít pro typ základní třídy System.Enum nebo konkrétní typ výčtu.
[System.Enum]::format([<enum-name>], <value>, <format-string>)
[<enum-name>]::format([<enum-name>], <value>, <format-string>)
Platné formátovací řetězce jsou G
nebo g
, D
nebo d
X
, nebo x
, a F
nebo .f
Další informace naleznete v tématu Výčtové formátovací řetězce.
Následující příklad používá každý z podporovaných řetězců formátu výčtu k převodu každé hodnoty výčtu TaskState na jeho řetězcové reprezentace.
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
Metoda GetEnumName()
reflexe vrátí název pro konkrétní hodnotu výčtu. Vstupní hodnota musí být platným základním typem pro výčet, například celé číslo nebo hodnotu výčtu. Pokud existuje více názvů přidružených k hodnotě, vrátí metoda první definovaný název.
[<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
Metoda GetEnumNames()
reflexe vrátí názvy pro každou hodnotu výčtu jako řetězce. Výstup obsahuje synonyma.
[<enum-name>].GetEnumNames()
enum Season {
Unknown
Spring
Summer
Autumn
Winter
Fall = 3
}
[Season].GetEnumNames()
Unknown
Spring
Summer
Fall
Autumn
Winter
GetEnumUnderlyingType
Metoda GetEnumUnderlyingType()
reflexe vrátí základní typ pro hodnoty výčtu.
[<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
Metoda GetEnumValues()
reflexe vrátí každou definovanou hodnotu pro výčet.
[<enum-name>].GetEnumValues()
enum Season {
Unknown
Spring
Summer
Autumn
Winter
Fall = 3
}
[Season].GetEnumValues()
Unknown
Spring
Summer
Fall
Fall
Winter
GetEnumValuesAsUnderlyingType
Metoda GetEnumValuesAsUnderlyingType()
reflexe vrátí každou definovanou hodnotu pro výčet jako základní typ.
[<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
Metoda HasFlag
instance určuje, zda je bit příznak nastaven pro hodnotu výčtu příznaku. Použití této metody je kratší a čitelnější než provádění binárního porovnání a kontroly ekvivalence.
<enum-value>.HasFlag(<enum-flag-value>)
Následující příklad definuje výčet příznaku ModuleFeatures a ukazuje, které příznaky má hodnota 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
IsDefined()
Statická metoda vrátí$true
, pokud je vstupní hodnota definována pro výčet a jinak $false
. Tato metoda slouží ke kontrole, zda je hodnota platná pro výčet, aniž by bylo nutné zpracovat chyby neplatných argumentů.
Statickou metodu můžete použít pro typ základní třídy System.Enum nebo konkrétní typ výčtu.
[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
Metoda ToString()
instance vrátí popisek pro hodnotu výčtu.
Tato metoda je také výchozím zobrazením, jak se hodnota výčtu zobrazuje jako výstup. Volitelně můžete zadat formátovací řetězec, který určuje způsob zobrazení hodnoty. Další informace o formátování naleznete v tématu Formátování výčtu hodnot.
Poznámka:
Pro výčty, které definují synonyma pro konkrétní hodnotu, nezapisujte kód, který závisí na výstupu ToString()
. Metoda může vrátit libovolný platný název hodnoty.
<enum-value>.ToString([<format-string>])
Následující příklad definuje shade výčtu jako Gray
synonymum pro Grey
. Pak vypíše objekty, které zobrazují skutečnou hodnotu výčtu, výčt jako řetězec a výčet jako celé číslo.
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
Synonyma hodnot výčtu
Můžete definovat výčty, které dávají různým názvům stejnou celočíselnou hodnotu. Když to uděláte, názvy, které odkazují na stejnou podkladovou hodnotu, se nazývají synonyma. Výčty se synonymy umožňují uživatelům zadat různé názvy pro stejnou hodnotu.
Při definování výčtu se synonymy nezapisujte kód, který závisí na hodnotě synonym, která se převádí na konkrétní název. Můžete spolehlivě napsat kód, který převede řetězec synonyma na hodnotu výčtu. Při práci se samotnou hodnotou výčtu ji vždy porovnejte jako hodnotu výčtu nebo jeho základního typu, nikoli jako řetězec.
Následující blok kódu definuje výčet Shade s synonymy Grey
a Gray
jako synonyma.
enum Shade {
White
Grey
Gray = 1
Black
}
[Shade]'Grey' -eq [Shade]::Gray
[Shade]::Grey -eq 1
[Shade]'Gray' -eq 1
True
True
True
Výčty jako příznaky
Jedním z běžných použití výčtu je reprezentace sady vzájemně se vylučujících hodnot. Například instance ArrivalStatus může mít hodnotu Early, OnTime nebo Late. Nemá smysl pro hodnotu instance ArrivalStatus odrážet více než jednu výčtovou konstantu.
V jiných případech však hodnota objektu výčtu může obsahovat více členů výčtu a každý člen představuje bitové pole v hodnotě výčtu. Příznak FlagsAttribute můžete použít k označení, že výčet se skládá z bitových polí jako příznaků, které mohou uživatelé kombinovat.
Aby výčty fungovaly správně jako příznaky, musíte nastavit celočíselnou hodnotu každého popisku na mocninu dvou. Pokud nezadáte hodnotu popisku, PowerShell nastaví hodnotu na jednu vyšší než předchozí popisek.
Můžete definovat hodnoty pro běžně používané kombinace příznaků, které uživatelům usnadní zadání sady příznaků najednou. Název hodnoty by měl být sloučené názvy příznaků. Celočíselná hodnota by měla být součet hodnot příznaku.
Chcete-li zjistit, zda je pro hodnotu nastaven určitý příznak, použijte HasFlag()
metodu pro hodnotu nebo použijte binární relační operátor -band
.
Ukázku ukazující, jak používat výčty příznaků a zkontrolovat, jestli je nastavený příznak, najdete v příkladu 3.
Výčty jako parametry
Můžete definovat parametry rutiny, které jako typ používají výčt. Když jako typ parametru zadáte výčet, uživatelé získají automatické dokončování a ověření hodnoty parametru. Dokončení argumentu navrhuje seznam platných popisků výčtu.
Pokud má parametr výčt jako jeho typ, můžete zadat některou z těchto možností:
- Výčet, například
[<EnumType>]::<Label>
- Popisek výčtu jako řetězec
- Číselná hodnota výčtu
Příklad znázorňující chování parametru typu výčtu naleznete v příkladu 4.
Výčty s konkrétními podkladovými typy
Počínaje PowerShellem 6.2 můžete definovat výčty s konkrétním základním typem. Když definujete výčet bez konkrétního základního typu, PowerShell vytvoří výčet s [int]
(System.Int32) jako základním typem.
Základní typ výčtu musí být celočíselný číselný typ. Následující seznam obsahuje platné typy s krátkým názvem a úplným názvem:
byte
- System.Bytesbyte
- System.SByteshort
- System.Int16ushort
- System.UInt16int
- System.Int32uint
- System.UInt32long
- System.Int64ulong
- System.UInt64
Můžete definovat konkrétní základní typ výčtu buď jako krátký název, nebo úplný název typu. Následující definice jsou funkčně identické. Liší se pouze název použitý pro podkladový typ.
enum LongValueEnum : long {
Zero
One
Two
}
enum LongValueEnum : System.Int64 {
Zero
One
Two
}
Formátování hodnot výčtu
Hodnoty výčtu můžete převést na jejich řetězcové reprezentace voláním static Format metoda, stejně jako přetížení instance ToString metoda. Řetězec formátu můžete použít k řízení přesného způsobu, jakým je hodnota výčtu reprezentována jako řetězec. Další informace naleznete v tématu Výčtové formátovací řetězce.
Následující příklad používá každý z podporovaných řetězců formátu výčtu (G
nebo g
, D
nebo d
, X
nebo x
, a F
nebo f
) k převodu každého člena výčtu TaskState na jeho řetězcové reprezentace.
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
Následující příklad používá formátovací řetězce pro hodnoty výčtu příznaku.
[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
Všimněte si, že pro výčty G
příznaků zobrazují řetězce a F
formátovací řetězce seznam příznaků sady pro hodnotu oddělenou čárkami. Poslední hodnota neobsahuje žádné příznaky, 8
protože ve skutečnosti není platná sada příznaků. Pokud chcete získat součet bez 8
duplikování alespoň jednoho příznaku, nemůžete kombinovat příznaky výčtu.
Definování rozšiřujících metod pomocí Update-TypeData
V deklaraci pro výčet nelze definovat metody. Chcete-li rozšířit funkce výčtu, můžete pomocí rutiny Update-TypeData definovat ScriptMethod
členy pro výčet.
Následující příklad používá rutinu Update-TypeData
GetFlags()
k přidání metody do výčtu příznaku FileAttributes . Vrátí pole příznaků nastavených pro hodnotu.
[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
Export výčtů pomocí akcelerátorů typů
Moduly PowerShellu ve výchozím nastavení automaticky nevyexportují třídy a výčty definované v PowerShellu. Vlastní typy nejsou k dispozici mimo modul bez volání using module
příkazu.
Pokud ale modul přidá akcelerátory typů, jsou tyto akcelerátory typů okamžitě dostupné v relaci po importu modulu uživateli.
Poznámka:
Přidání akcelerátorů typů do relace používá interní (ne veřejné) rozhraní API. Použití tohoto rozhraní API může způsobit konflikty. Následující vzor vyvolá chybu, pokud při importu modulu již existuje akcelerátor typu se stejným názvem. Odebere také akcelerátory typů, když modul odeberete z relace.
Tento model zajišťuje, že typy jsou k dispozici v relaci. Nemá vliv na IntelliSense ani dokončování při vytváření souboru skriptu ve VS Code.
Pokud chcete získat návrhy IntelliSense a dokončování pro vlastní typy v editoru VS Code, musíte do horní části skriptu přidat using module
příkaz.
Následující model ukazuje, jak v modulu zaregistrovat třídy PowerShellu a výčty jako akcelerátory typů. Přidejte fragment kódu do modulu kořenového skriptu za definice typu. Ujistěte se, že $ExportableTypes
proměnná obsahuje každý z typů, které chcete uživatelům zpřístupnit při importu modulu. Druhý kód nevyžaduje žádné úpravy.
# 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()
Když uživatelé modul naimportují, všechny typy přidané do akcelerátorů typů pro relaci jsou okamžitě dostupné pro IntelliSense a dokončení. Když se modul odebere, jedná se tedy o akcelerátory typů.
Ruční import výčtů z modulu PowerShellu
Import-Module
#requires
a příkaz importuje pouze funkce modulu, aliasy a proměnné, jak je definováno modulem. Výčty se neimportují.
Pokud modul definuje třídy a výčty, ale nepřidá akcelerátory typů pro tyto typy, použijte k jejich importu using module
příkaz.
Příkaz using module
importuje třídy a výčty z kořenového modulu (ModuleToProcess
) modulu skriptu nebo binárního modulu. Neimportuje konzistentně třídy definované v vnořených modulech nebo třídách definovaných ve skriptech, které jsou do kořenového modulu dot-source. Definujte třídy, které chcete zpřístupnit uživatelům mimo modul přímo v kořenovém modulu.
Další informace o using
příkazu najdete v tématu about_Using.
Načítání nově změněný kód během vývoje
Při vývoji modulu skriptu je běžné provádět změny kódu a pak načíst novou verzi modulu pomocí Import-Module
parametru Force . To funguje jenom pro změny funkcí v kořenovém modulu. Import-Module
nenačítá žádné vnořené moduly. Neexistuje také způsob, jak načíst žádné aktualizované třídy.
Abyste měli jistotu, že používáte nejnovější verzi, musíte spustit novou relaci.
Třídy a výčty definované v PowerShellu a importované pomocí using
příkazu se nedají uvolnit.
Dalším běžným postupem vývoje je oddělení kódu do různých souborů. Pokud máte funkci v jednom souboru, který používá výčty definované v jiném modulu, měli byste pomocí using module
příkazu zajistit, aby funkce měly potřebné definice výčtu.
Omezení
Hodnoty výčtu definované v PowerShellu nemůžete ozdobit atributy. Můžete pouze ozdobit samotnou deklaraci výčtu, stejně jako u FlagsAttribute pro definování výčtu jako sady bitových příznaků.
Řešení: Žádné
V definicích výčtu nemůžete definovat metody a PowerShell nepodporuje definování [rozšiřujících metod] jako C#.
Alternativní řešení: K definování
ScriptMethod
členů výčtu použijte rutinu Update-TypeData.