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. Tego wyliczenia można użyć w kodzie bez konieczności analizowania lub sprawdzania błędów pisowni.
Wyliczenia są wewnętrznie reprezentowane jako typy wartości całkowitych z początkową wartością zero. Domyślnie wyliczenia programu PowerShell używają elementu 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>]
...
}
Składnia wyliczenia określonego 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 wyliczenia
[<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 bazowych wartości music
, , picture
video
. Etykiety natychmiast po jawnym przypisaniu uzyskują 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 mpg
jpg
jpeg
, . 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()
wydają się zwracać te same wyniki; lista nazwanych wartości. Jednak wewnętrznie GetEnumValues()
wylicza wartości, a następnie mapuje wartości na nazwy. Uważnie odczytaj listę i zauważysz, że ogg
element , oga
i mogg
pojawi się w danych wyjściowych GetEnumNames()
GetEnumValues()
polecenia , ale dane wyjściowe są wyświetlane ogg
tylko w pliku . 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ść wyliczeniową według etykiety za pomocą 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ść dla 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 ustawiono konkretną flagę, możesz użyć operatora -band
porównania binarnego . W tym przykładzie testuje atrybuty Device i Archive 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 ustawiono konkretną flagę.
W tym przykładzie testuje 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 z 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
W tym przykładzie pierwsza instrukcja wywołująca ConvertTo-LineEndingRegex
przekazuje wartość wyliczenia dla elementu CR
. Druga instrukcja przekazuje ciąg 'CRLF'
, który jest rzutowy na lineEnding. Trzecia instrukcja określa wartość 2
parametru, który mapuje 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 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 z określonym typem 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
jest tablicą zawierającą 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
. Zdefiniowane wyliczenie używa określonego typu całkowitego jako podstawowego typu wartości.Wyliczenie jest definiowane z wartością
Min
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 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 wyliczania w programie PowerShell i sposób ich używania.
Formatuj
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łanie metody ToString dla wartości z określonym ciągiem formatu.
Można 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
, D
g
lub d
X
, lub x
lub F
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 jego 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 dla 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ść dla 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 sprawdzenia 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ść, jeśli wartość wejściowa jest zdefiniowana 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 sposobu wyświetlania wartości wyliczenia jako danych wyjściowych. 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 zależnego od danych wyjściowych elementu 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 dają różne nazwy tej samej wartości całkowitej. Gdy to zrobisz, 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 należy zawsze porównać ją jako wartość wyliczenia lub jego typ bazowy zamiast jako ciąg.
Poniższy blok kodu definiuje wyliczenie Shade z elementami Grey
i Gray
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 flag, 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 moc 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 operatora -band
porównania binarnego .
Aby zapoznać się z przykładem pokazującym, jak używać wyliczenia flagi i sprawdzić, czy flaga jest ustawiona, zobacz Przykład 3.
Wyliczenia jako parametry
Możesz 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 jego typ, można określić dowolny z:
- Wyliczenie, na przykład
[<EnumType>]::<Label>
- Etykieta wyliczenia jako ciąg
- Wartość liczbowa wyliczenia
Aby zapoznać się z przykładem pokazują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. Możesz użyć ciągu formatu, aby 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 D
g
, lub X
d
lub x
) F
f
w celu przekonwertowania każdego elementu członkowskiego 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
F
że w przypadku wyliczenia flag i ciągi formatu wyświetlają listę flag zestawu dla wartości 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ą metody 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 użyto Update-TypeData
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 wyliczeń 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. Użycie 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 podczas usuwania modułu z sesji.
Ten wzorzec gwarantuje, że typy są dostępne w sesji. Nie ma to wpływu na funkcję IntelliSense ani uzupełnianie podczas tworzenia pliku skryptu w programie VS Code.
Aby uzyskać sugestie dotyczące funkcji IntelliSense i 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 programu PowerShell i wyliczenia jako akceleratory typów w module. Dodaj fragment kodu do modułu skryptu głównego po dowolnych 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 wszystkie 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 wyliczeń 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 importuje spójnie klas zdefiniowanych w zagnieżdżonych modułach ani 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 ładują 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 wyliczeń 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. Możesz udekorować tylko samą deklarację wyliczenia, tak jak w przypadku 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.