about_Enum
Krótki opis
Instrukcja enum
deklaruje wyliczenie. Wyliczenie jest odrębnym typem, który składa się z zestawu nazwanych etykiet nazywanych listą modułów wyliczających.
Długi opis
Instrukcja enum
umożliwia utworzenie silnie typizowanego zestawu etykiet. Możesz użyć tej wyliczenia w kodzie bez konieczności analizowania lub sprawdzania błędów pisowni.
Wyliczenia są wewnętrznie reprezentowane jako typy wartości całkowitych z wartością początkową zero. Domyślnie wyliczenia programu PowerShell używają parametru System.Int32 ([int]
) jako typu bazowego. Domyślnie program PowerShell przypisuje pierwszą etykietę na liście wartość zero. Domyślnie program PowerShell przypisuje pozostałe etykiety z kolejnymi liczbami całkowitymi.
W definicji można nadać etykietom dowolną wartość całkowitą. Etykiety bez przypisanej wartości przyjmują następną wartość całkowitą.
Składnia
Wyliczenia używają następujących składni:
Składnia definicji wyliczenia liczb całkowitych
[[<attribute>]...] enum <enum-name> {
<label> [= <int-value>]
...
}
Określona składnia definicji wyliczenia typu bazowego
[[<attribute>]...] enum <enum-name> : <underlying-type-name> {
<label> [= <int-value>]
...
}
Składnia definicji wyliczenia flagi
[[<attribute>]...] [Flag()] enum <enum-name>[ : <underlying-type-name>] {
<label 0> [= 1]
<label 1> [= 2]
<label 2> [= 4]
<label 3> [= 8]
...
...
}
Składnia dostępu do wyliczania
[<enum-name>]::<label>
Przykłady
Przykład 1 — minimalna wyliczenie
Poniższy blok kodu definiuje wyliczenie MarkdownUnorderedListCharacter z trzema etykietami. Nie przypisuje jawnych wartości do żadnej etykiety.
enum MarkdownUnorderedListCharacter {
Asterisk
Dash
Plus
}
Następny blok kodu pokazuje, jak zachowują się zarówno wartości całkowite, jak i ciągowe podczas rzutowania do typu wyliczenia.
$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
Rzutowanie liczb całkowitych, które są równe wartości wyliczenia, zwraca ten wyliczenie. Rzutowanie ciągów, które są takie same jak etykieta wyliczenia zwraca tę wyliczenie.
Przykład 2 — jawne i synonimowe wartości wyliczenia
W poniższym przykładzie przedstawiono wyliczenie obiektów skorelowanych z plikami multimedialnymi. Definicja przypisuje jawne wartości do podstawowych wartości , music
, picture
video
. Etykiety natychmiast po jawnym przypisaniu otrzymują następną wartość całkowitą. Synonimy można utworzyć, przypisując tę samą wartość do innej etykiety; Zobacz skonstruowane wartości dla: ogg
, , oga
mogg
lub jpg
jpeg
, .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
}
Metoda GetEnumNames()
zwraca listę etykiet dla wyliczenia.
[MediaTypes].GetEnumNames()
unknown
music
mp3
aac
ogg
oga
mogg
picture
jpg
jpeg
png
video
mpg
mpeg
avi
m4v
Metoda GetEnumValues()
zwraca listę wartości wyliczenia.
[MediaTypes].GetEnumValues()
unknown
music
mp3
aac
ogg
ogg
ogg
picture
jpg
jpg
png
video
mpg
mpg
avi
m4v
Uwaga
GetEnumNames()
i GetEnumValues()
wydaje się zwracać te same wyniki; lista nazwanych wartości. Jednak wewnętrznie wylicza wartości, GetEnumValues()
a następnie mapuje wartości na nazwy. Uważnie przeczytaj listę i zauważysz, że ogg
element , oga
i mogg
pojawi się w danych wyjściowych polecenia GetEnumNames()
, ale dane wyjściowe GetEnumValues()
są wyświetlane ogg
tylko . Dzieje się tak samo w przypadku jpg
, jpeg
i mpg
, mpeg
. Nazwa programu PowerShell zwraca wartość dla wartości synonimów nie jest deterministyczna.
Możesz użyć GetEnumName()
metody , aby uzyskać nazwę skojarzona z określoną wartością. Jeśli istnieje wiele nazw skojarzonych z wartością, metoda zwraca pierwszą zdefiniowaną nazwę.
[MediaTypes].GetEnumName(15)
ogg
W poniższym przykładzie pokazano, jak zamapować każdą nazwę na jej wartość.
[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
Można określić pojedynczą wartość wyliczenia według etykiety przy użyciu składni [<enum-name>]::<label>
.
[MediaTypes]::png
[MediaTypes]::png -eq 22
png
True
Przykład 3 — Wyliczenie jako flagi
Poniższy blok kodu tworzy wyliczenie FileAttributes jako zestaw flag bitowych. Wartość każdej etykiety jest dwukrotnie częścią poprzedniej etykiety.
[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
Aby sprawdzić, czy jest ustawiona określona flaga, możesz użyć operatora -band
porównania binarnego . W tym przykładzie testuje atrybuty Urządzenie i Archiwum w wartości $file2
.
PS > ($file2 -band [FileAttributes]::Device) -eq [FileAttributes]::Device
True
PS > ($file2 -band [FileAttributes]::Archive) -eq [FileAttributes]::Archive
False
Możesz również użyć HasFlag()
metody , aby sprawdzić, czy jest ustawiona określona flaga.
W tym przykładzie testowane są atrybuty Urządzenie i Ukryte w wartości $file1
.
PS > $file1.HasFlag([FileAttributes]::Device)
True
PS > $file1.HasFlag([FileAttributes]::Hidden)
False
Przykład 4 — Wyliczenie jako parametr
W poniższym przykładzie funkcja ConvertTo-LineEndingRegex
definiuje parametr InputObject o typie 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
W tym przykładzie pierwsza instrukcja wywołująca ConvertTo-LineEndingRegex
przekazuje wartość wyliczenia dla CR
elementu . Druga instrukcja przekazuje ciąg 'CRLF'
, który jest rzutowy na lineEnding. Trzecia instrukcja określa wartość 2
parametru, który jest mapowy na etykietę LF
.
Opcje uzupełniania argumentów można wyświetlić, wpisując następujący tekst w wierszu polecenia programu PowerShell:
ConvertTo-LineEndingRegex -InputObject <Tab>
Po określeniu nieprawidłowej nazwy etykiety lub wartości liczbowej dla parametru funkcja zgłasza błąd.
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".
Przykład 5 — Wyliczenie z określonymi typami bazowymi
Począwszy od programu PowerShell 6.2, można zdefiniować wyliczenia o określonym typie bazowym. W tym przykładzie przedstawiono prawidłowe typy bazowe dla wyliczenia.
Pierwszy blok kodu inicjuje dwie zmienne jako tablice. $EnumTypes
jest pustą tablicą do przechowywania dynamicznie utworzonych typów. $IntegralTypes
to tablica zawierająca prawidłowe typy bazowe dla wyliczenia.
$EnumTypes = @()
$IntegralTypes = @(
'byte', 'sbyte', 'short', 'ushort', 'int', 'uint', 'long', 'ulong'
)
Następny blok kodu definiuje szablon używany do dynamicznego tworzenia definicji wyliczenia. {0}
Gdy symbol zastępczy formatu zostanie zastąpiony nazwą typu całkowitego, szablon tworzy blok skryptu, który:
Definiuje wyliczenie o nazwie
<type>Enum
, na przykładbyteEnum
. Zdefiniowana wyliczenie używa określonego typu całkowitego jako typu wartości bazowej.Wyliczenie jest definiowane z
Min
wartością ustawioną na wartość minimalną dla typu całkowitego. DefiniujeMax
wartość ustawioną na wartość maksymalną dla typu całkowitego.Zwraca nowo zdefiniowany typ.
$DefinitionTemplate = @"
enum {0}Enum : {0} {{
Min = [{0}]::MinValue
Max = [{0}]::MaxValue
}}
[{0}Enum]
"@
Następny blok kodu używa szablonu do utworzenia i wywołania blokady skryptu w bieżącym zakresie. Dodaje ona zwracane definicje typów do tablicy $EnumTypes
.
foreach ($IntegralType in $IntegralTypes) {
$Definition = $DefinitionTemplate -f $IntegralType
$ScriptBlock = [scriptblock]::Create($Definition)
$EnumTypes += . $ScriptBlock
}
Ostatni blok kodu wykonuje pętle na typach wyliczenia przy użyciu GetEnumValuesAsUnderlyingType()
metody , aby wyświetlić wartości jako typ bazowy. Pętla tworzy nowy obiekt dla każdej wartości, pokazując typ wyliczenia, typ wartości, etykietę i rzeczywistą wartość.
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 wyliczania
Poniższa lista zawiera przydatne metody dostępne do wyliczenia w programie PowerShell i sposób ich używania.
Format
Metoda statyczna Format()
zwraca sformatowane dane wyjściowe ciągu dla danego typu wyliczenia, wartości wyliczenia i ciągu formatu. Dane wyjściowe są takie same jak wywoływanie metody ToString w wartości z określonym ciągiem formatu.
Możesz użyć metody statycznej w typie klasy bazowej System.Enum lub określonym typie wyliczenia.
[System.Enum]::format([<enum-name>], <value>, <format-string>)
[<enum-name>]::format([<enum-name>], <value>, <format-string>)
Prawidłowe ciągi formatu to G
, g
D
lub d
, X
lub x
F
lub lub f
. Aby uzyskać więcej informacji, zobacz Ciągi formatu wyliczenia.
W poniższym przykładzie użyto każdego z obsługiwanych ciągów formatu wyliczenia, aby przekonwertować każdą wartość wyliczenia TaskState na reprezentacje ciągów.
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()
odbicia zwraca nazwę określonej wartości wyliczenia. Wartość wejściowa musi być prawidłowym typem bazowym dla wyliczenia, takiego jak liczba całkowita lub wartość wyliczenia. Jeśli istnieje wiele nazw skojarzonych z wartością, metoda zwraca pierwszą zdefiniowaną nazwę.
[<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()
odbicia zwraca nazwy każdej wartości wyliczenia jako ciągi. Dane wyjściowe zawierają synonimy.
[<enum-name>].GetEnumNames()
enum Season {
Unknown
Spring
Summer
Autumn
Winter
Fall = 3
}
[Season].GetEnumNames()
Unknown
Spring
Summer
Fall
Autumn
Winter
GetEnumUnderlyingType
Metoda GetEnumUnderlyingType()
odbicia zwraca podstawowy typ wartości wyliczenia.
[<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()
odbicia zwraca każdą zdefiniowaną wartość wyliczenia.
[<enum-name>].GetEnumValues()
enum Season {
Unknown
Spring
Summer
Autumn
Winter
Fall = 3
}
[Season].GetEnumValues()
Unknown
Spring
Summer
Fall
Fall
Winter
GetEnumValuesAsUnderlyingType
Metoda GetEnumValuesAsUnderlyingType()
odbicia zwraca każdą zdefiniowaną wartość wyliczenia jako typ bazowy.
[<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
wystąpienia określa, czy flaga bitowa jest ustawiona dla wartości wyliczenia flagi. Użycie tej metody jest krótsze i łatwiejsze do odczytania niż przeprowadzenie porównania binarnego i sprawdzania równoważności.
<enum-value>.HasFlag(<enum-flag-value>)
W poniższym przykładzie zdefiniowano wyliczenie flagi ModuleFeatures i pokazano, które flagi mają wartość 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
Metoda statyczna IsDefined()
zwraca $true
wartość wejściową zdefiniowaną dla wyliczenia i w przeciwnym razie $false
. Użyj tej metody, aby sprawdzić, czy wartość jest prawidłowa dla wyliczenia bez konieczności obsługi nieprawidłowych błędów argumentów.
Można użyć metody statycznej w typie klasy bazowej System.Enum lub określonym typie wyliczenia.
[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()
wystąpienia zwraca etykietę dla wartości wyliczenia.
Ta metoda jest również widokiem domyślnym, w jaki sposób wartość wyliczenia jest wyświetlana jako dane wyjściowe. Opcjonalnie możesz określić ciąg formatu, aby kontrolować sposób wyświetlania wartości. Aby uzyskać więcej informacji na temat formatowania, zobacz Formatowanie wartości wyliczenia.
Uwaga
W przypadku wyliczeń definiujących synonimy dla określonej wartości nie należy pisać kodu, który zależy od danych wyjściowych .ToString()
Metoda może zwrócić dowolną prawidłową nazwę dla wartości.
<enum-value>.ToString([<format-string>])
W poniższym przykładzie zdefiniowano wyliczenie Shade jako Gray
synonim dla elementu Grey
. Następnie zwraca obiekty, które pokazują rzeczywistą wartość wyliczenia, wyliczenie jako ciąg i wyliczenie jako liczbę całkowitą.
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
Synonimy wartości wyliczenia
Można zdefiniować wyliczenia, które nadają różne nazwy tej samej wartości całkowitej. W takim przypadku nazwy wskazujące tę samą wartość bazowa są nazywane synonimami. Wyliczenia z synonimami umożliwiają użytkownikom określanie różnych nazw dla tej samej wartości.
Podczas definiowania wyliczenia z synonimami nie należy pisać kodu, który zależy od wartości synonimu konwertowanej na określoną nazwę. Można niezawodnie napisać kod, który konwertuje ciąg synonimu na wartość wyliczenia. Podczas pracy z samą wartością wyliczenia zawsze porównuj ją jako wartość wyliczenia lub jej typ bazowy, a nie jako ciąg.
Poniższy blok kodu definiuje wyliczenie Shade z Grey
Gray
i jako synonimy.
enum Shade {
White
Grey
Gray = 1
Black
}
[Shade]'Grey' -eq [Shade]::Gray
[Shade]::Grey -eq 1
[Shade]'Gray' -eq 1
True
True
True
Wyliczenia jako flagi
Jednym z typowych zastosowań wyliczenia jest reprezentowanie zestawu wzajemnie wykluczających się wartości. Na przykład wystąpienie ArrivalStatus może mieć wartość Early, OnTime lub Late. Nie ma sensu, aby wartość wystąpienia ArrivalStatus odzwierciedlała więcej niż jedną stałą wyliczenia.
W innych przypadkach jednak wartość obiektu wyliczenia może zawierać wiele elementów członkowskich wyliczenia, a każdy element członkowski reprezentuje pole bitowe w wartości wyliczenia. Możesz użyć atrybutu FlagsAttribute , aby wskazać, że wyliczenie składa się z pól bitowych jako flagi, które użytkownicy mogą łączyć.
Aby wyliczenia jako flagi działały prawidłowo, należy ustawić wartość całkowitą każdej etykiety na potęgę dwóch. Jeśli nie określisz wartości etykiety, program PowerShell ustawi wartość na wyższą niż poprzednia etykieta.
Można zdefiniować wartości dla często używanych kombinacji flag, aby ułatwić użytkownikom określenie zestawu flag jednocześnie. Nazwa wartości powinna być połączonymi nazwami flag. Wartość całkowita powinna być sumą wartości flagi.
Aby określić, czy określona flaga jest ustawiona dla wartości, użyj HasFlag()
metody w wartości lub użyj binarnego operatora -band
porównania .
Aby zapoznać się z przykładem pokazującym, jak używać wyliczenia flag i sprawdzić, czy ustawiono flagę, zobacz Przykład 3.
Wyliczenia jako parametry
Można zdefiniować parametry polecenia cmdlet, które używają wyliczenia jako ich typu. Po określeniu wyliczenia jako typu parametru użytkownicy uzyskują automatyczne uzupełnianie i walidację wartości parametru. Uzupełnianie argumentu sugeruje listę prawidłowych etykiet dla wyliczenia.
Jeśli parametr ma wyliczenie jako typ, możesz określić dowolną z:
- Wyliczenie, na przykład
[<EnumType>]::<Label>
- Etykieta wyliczenia jako ciąg
- Wartość liczbowa wyliczenia
Aby zapoznać się z przykładem przedstawiającym zachowanie parametru typu wyliczenia, zobacz Przykład 4.
Wyliczenia z określonymi typami bazowymi
Począwszy od programu PowerShell 6.2, można zdefiniować wyliczenia z określonym typem bazowym. Podczas definiowania wyliczenia bez określonego typu bazowego program PowerShell tworzy wyliczenie [int]
(System.Int32) jako typ bazowy.
Podstawowym typem wyliczenia musi być całkowity typ liczbowy. Poniższa lista zawiera prawidłowe typy z krótką nazwą i pełną nazwą typu:
byte
- System.Bytesbyte
- System.SByteshort
- System.Int16ushort
- System.UInt16int
- System.Int32uint
- System.UInt32long
- System.Int64ulong
- System.UInt64
Można zdefiniować określony typ bazowy dla wyliczenia jako krótką nazwę lub pełną nazwę typu. Poniższe definicje są funkcjonalnie identyczne. Tylko nazwa używana dla typu bazowego jest inna.
enum LongValueEnum : long {
Zero
One
Two
}
enum LongValueEnum : System.Int64 {
Zero
One
Two
}
Formatowanie wartości wyliczenia
Wartości wyliczenia można przekonwertować na ich reprezentacje ciągów, wywołując metodę static Format , a także przeciążenia metody ToString wystąpienia. Za pomocą ciągu formatu można kontrolować dokładny sposób, w jaki wartość wyliczenia jest reprezentowana jako ciąg. Aby uzyskać więcej informacji, zobacz Ciągi formatu wyliczenia.
W poniższym przykładzie użyto każdego z obsługiwanych ciągów formatu wyliczenia (G
lub g
D
, lub d
X
lub x
lub F
f
), aby przekonwertować każdy element członkowski wyliczenia TaskState na jego reprezentacje ciągów.
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
W poniższym przykładzie użyto ciągów formatu dla wartości wyliczenia flagi.
[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
Zwróć uwagę, G
że w przypadku wyliczenia flag ciągi i F
zawierają listę flag zestawów rozdzielonych przecinkami. Ostatnia wartość , nie wyświetla żadnych flag, 8
ponieważ w rzeczywistości nie jest to prawidłowy zestaw flag. Nie można połączyć flag wyliczenia, aby uzyskać sumę 8
bez duplikowania co najmniej jednej flagi.
Definiowanie metod rozszerzeń za pomocą Update-TypeData
Nie można zdefiniować metod w deklaracji dla wyliczenia. Aby rozszerzyć funkcjonalność wyliczenia, możesz użyć polecenia cmdlet Update-TypeData , aby zdefiniować ScriptMethod
elementy członkowskie dla wyliczenia.
W poniższym przykładzie Update-TypeData
użyto polecenia cmdlet , aby dodać metodę GetFlags()
do wyliczenia flagi FileAttributes . Zwraca tablicę flag ustawionych dla wartości.
[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
Eksportowanie wyliczenia z akceleratorami typów
Domyślnie moduły programu PowerShell nie eksportują automatycznie klas i wyliczenia zdefiniowanych w programie PowerShell. Typy niestandardowe nie są dostępne poza modułem bez wywoływania instrukcji using module
.
Jeśli jednak moduł dodaje akceleratory typów, akceleratory tego typu są natychmiast dostępne w sesji po zaimportowaniu modułu przez użytkowników.
Uwaga
Dodawanie akceleratorów typów do sesji używa wewnętrznego (nie publicznego) interfejsu API. Korzystanie z tego interfejsu API może powodować konflikty. Wzorzec opisany poniżej zgłasza błąd, jeśli akcelerator typu o tej samej nazwie już istnieje podczas importowania modułu. Usuwa również akceleratory typów po usunięciu modułu z sesji.
Ten wzorzec zapewnia dostępność typów w sesji. Nie ma to wpływu na funkcję IntelliSense ani uzupełnianie podczas tworzenia pliku skryptu w programie VS Code.
Aby uzyskać funkcję IntelliSense i sugestie uzupełniania dla typów niestandardowych w programie VS Code, należy dodać instrukcję using module
na początku skryptu.
Poniższy wzorzec pokazuje, jak zarejestrować klasy i wyliczenia programu PowerShell jako akceleratory typów w module. Dodaj fragment kodu do modułu głównego skryptu po wszelkich definicjach typów. Upewnij się, że zmienna $ExportableTypes
zawiera każdy z typów, które mają być dostępne dla użytkowników podczas importowania modułu. Drugi kod nie wymaga edycji.
# 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()
Podczas importowania modułu przez użytkowników wszelkie typy dodane do akceleratorów typów dla sesji są natychmiast dostępne dla funkcji IntelliSense i uzupełniania. Po usunięciu modułu są więc akceleratory typów.
Ręczne importowanie wyliczenia z modułu programu PowerShell
Import-Module
i instrukcja #requires
importuje tylko funkcje modułu, aliasy i zmienne, zgodnie z definicją w module. Wyliczenia nie są importowane.
Jeśli moduł definiuje klasy i wyliczenia, ale nie dodaje akceleratorów typów dla tych typów, użyj using module
instrukcji , aby je zaimportować.
Instrukcja using module
importuje klasy i wyliczenia z modułu głównego (ModuleToProcess
) modułu skryptu lub modułu binarnego. Nie powoduje spójnego importowania klas zdefiniowanych w zagnieżdżonych modułach lub klasach zdefiniowanych w skryptach, które są dot-source do modułu głównego. Zdefiniuj klasy, które mają być dostępne dla użytkowników spoza modułu bezpośrednio w module głównym.
Aby uzyskać więcej informacji na temat instrukcji using
, zobacz about_Using.
Ładowanie nowo zmienionego kodu podczas programowania
Podczas opracowywania modułu skryptu często wprowadza się zmiany w kodzie, a następnie ładuje nową wersję modułu przy użyciu Import-Module
parametru Force . Działa to tylko w przypadku zmian funkcji w module głównym. Import-Module
nie ładuje ponownie żadnych zagnieżdżonych modułów. Ponadto nie ma możliwości załadowania zaktualizowanych klas.
Aby upewnić się, że używasz najnowszej wersji, musisz uruchomić nową sesję.
Nie można zwolnić klas i wyliczenia zdefiniowanych w programie PowerShell i zaimportowanych za pomocą using
instrukcji .
Innym typowym rozwiązaniem programistycznym jest rozdzielenie kodu na różne pliki. Jeśli masz funkcję w jednym pliku, który używa wyliczenia zdefiniowanych w innym module, należy użyć using module
instrukcji , aby upewnić się, że funkcje mają wymagane definicje wyliczenia.
Ograniczenia
Nie można dekorować wartości wyliczenia zdefiniowanych w programie PowerShell za pomocą atrybutów. Deklarację wyliczenia można dekorować tylko za pomocą atrybutu FlagsAttribute do definiowania wyliczenia jako zestawu flag bitowych.
Obejście: Brak
Nie można definiować metod wewnątrz definicji wyliczenia, a program PowerShell nie obsługuje definiowania [metod rozszerzeń], takich jak C#.
Obejście: Użyj polecenia cmdlet Update-TypeData , aby zdefiniować
ScriptMethod
elementy członkowskie dla wyliczenia.