about_Enum
Краткое описание
Инструкция enum
объявляет перечисление. Перечисление — это отдельный тип, состоящий из набора именованных меток, называемых списком перечислителя.
Подробное описание
Инструкция enum
позволяет создать строго типизированный набор меток. Это перечисление можно использовать в коде, не выполняя синтаксический анализ или проверку ошибок орфографии.
Перечисления являются внутренними типами целочисленных значений с начальным значением нуля. По умолчанию перечисления PowerShell используют System.Int32 ([int]
) в качестве базового типа. По умолчанию PowerShell назначает первую метку в списке нулевого значения. По умолчанию PowerShell назначает оставшиеся метки с последовательными целыми числами.
В определении можно указать метки любого целочисленного значения. Метки без присвоенного значения принимают следующее целочисленное значение.
Синтаксис
Перечисления используют следующие синтаксисы:
Синтаксис определения определения целочисленного перечисления
[[<attribute>]...] enum <enum-name> {
<label> [= <int-value>]
...
}
Синтаксис определения перечисления конкретного базового типа
[[<attribute>]...] enum <enum-name> : <underlying-type-name> {
<label> [= <int-value>]
...
}
Синтаксис определения перечисления флагов
[[<attribute>]...] [Flag()] enum <enum-name>[ : <underlying-type-name>] {
<label 0> [= 1]
<label 1> [= 2]
<label 2> [= 4]
<label 3> [= 8]
...
...
}
Синтаксис доступа перечисления
[<enum-name>]::<label>
Примеры
Пример 1. Минимальное перечисление
Следующий блок кода определяет перечисление MarkdownUnorderedListCharacter с тремя метками. Он не назначает явные значения метки.
enum MarkdownUnorderedListCharacter {
Asterisk
Dash
Plus
}
Следующий блок кода показывает, как ведут себя целые и строковые значения при приведении к типу перечисления.
$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
Приведение целых чисел, равных значению перечисления, возвращает это перечисление. Приведение строк, которые совпадают с меткой перечисления, возвращает это перечисление.
Пример 2. Значения перечисления явных и синонимов
В следующем примере показано перечисление объектов, которые коррелируют с файлами мультимедиа. Определение назначает явные значения базовым значениям music
, . picture
video
Метки сразу после явного назначения получают следующее целочисленное значение. Синонимы можно создать, назначив одно и то же значение другой метки; см. созданные значения для: ogg
, oga
, mogg
или 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
}
Метод GetEnumNames()
возвращает список меток для перечисления.
[MediaTypes].GetEnumNames()
unknown
music
mp3
aac
ogg
oga
mogg
picture
jpg
jpeg
png
video
mpg
mpeg
avi
m4v
Метод GetEnumValues()
возвращает список значений перечисления.
[MediaTypes].GetEnumValues()
unknown
music
mp3
aac
ogg
ogg
ogg
picture
jpg
jpg
png
video
mpg
mpg
avi
m4v
Примечание.
GetEnumNames()
и GetEnumValues()
, кажется, возвращает те же результаты; список именованных значений. Однако внутренне GetEnumValues()
перечисляет значения, а затем сопоставляет значения с именами. Внимательно прочтите список, и вы заметите, что oga
ogg
, и mogg
отображается в выходных GetEnumValues()
данныхGetEnumNames()
, но выходные данные отображаются ogg
только . То же самое происходит для jpg
, jpeg
и mpg
, mpeg
. Имя PowerShell возвращает значения синонимов не является детерминированным.
Метод можно использовать GetEnumName()
для получения имени, связанного с определенным значением. При наличии нескольких имен, связанных со значением, метод возвращает первое определенное имя.
[MediaTypes].GetEnumName(15)
ogg
В следующем примере показано, как сопоставить каждое имя со значением.
[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
Вы можете указать одно значение перечисления по метки с синтаксисом [<enum-name>]::<label>
.
[MediaTypes]::png
[MediaTypes]::png -eq 22
png
True
Пример 3. Перечисление в виде флагов
Следующий блок кода создает перечисление FileAttributes в виде набора битовых флагов. Значение каждой метки является двойным значением предыдущей метки.
[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
Чтобы проверить, задан ли определенный флаг, можно использовать оператор -band
двоичного сравнения. В этом примере проверяются атрибуты устройства и архива в значении $file2
.
PS > ($file2 -band [FileAttributes]::Device) -eq [FileAttributes]::Device
True
PS > ($file2 -band [FileAttributes]::Archive) -eq [FileAttributes]::Archive
False
Этот метод также можно использовать HasFlag()
для проверки того, задан ли определенный флаг.
В этом примере тесты для атрибутов Device и Hidden в значении $file1
.
PS > $file1.HasFlag([FileAttributes]::Device)
True
PS > $file1.HasFlag([FileAttributes]::Hidden)
False
Пример 4. Перечисление в качестве параметра
В следующем примере функция ConvertTo-LineEndingRegex
определяет параметр InputObject с типом 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
В примере первый вызов ConvertTo-LineEndingRegex
инструкции передает значение перечисления для CR
. Вторая инструкция передает строку 'CRLF'
, которая приводится к LineEnding. Третья инструкция указывает значение 2
параметра, которое сопоставляется с LF
меткой.
Параметры завершения аргументов можно просмотреть, введя следующий текст в запрос PowerShell:
ConvertTo-LineEndingRegex -InputObject <Tab>
При указании недопустимого имени метки или числового значения параметра функция вызывает ошибку.
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".
Пример 5. Перечисления с определенными базовыми типами
Начиная с PowerShell 6.2, можно определить перечисления с определенным базовым типом. В этом примере показаны допустимые базовые типы для перечисления.
Первый блок кода инициализирует две переменные в виде массивов. $EnumTypes
— пустой массив для хранения динамически созданных типов. $IntegralTypes
— это массив, содержащий допустимые базовые типы перечисления.
$EnumTypes = @()
$IntegralTypes = @(
'byte', 'sbyte', 'short', 'ushort', 'int', 'uint', 'long', 'ulong'
)
Следующий блок кода определяет шаблон для динамического создания определений перечисления. {0}
При замене заполнителя формата целочисленным именем типа шаблон создает блок скрипта, который:
Определяет перечисление с именем
<type>Enum
, напримерbyteEnum
. Определенное перечисление использует указанный целочисленный тип в качестве базового типа значения.Перечисление определяется с
Min
заданным значением минимальное значение для целочисленного типа. Он определяетMax
значение, заданное в максимальное значение целочисленного типа.Возвращает только что определенный тип.
$DefinitionTemplate = @"
enum {0}Enum : {0} {{
Min = [{0}]::MinValue
Max = [{0}]::MaxValue
}}
[{0}Enum]
"@
Следующий блок кода использует шаблон для создания и вызова блока скриптов в текущей области. Он добавляет возвращаемые определения типов в $EnumTypes
массив.
foreach ($IntegralType in $IntegralTypes) {
$Definition = $DefinitionTemplate -f $IntegralType
$ScriptBlock = [scriptblock]::Create($Definition)
$EnumTypes += . $ScriptBlock
}
Последний блок кода циклирует по типам перечисления, используя GetEnumValuesAsUnderlyingType()
метод для перечисления значений в качестве базового типа. Цикл создает новый объект для каждого значения, показывающий тип перечисления, тип значения, метку и фактическое значение.
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
Методы перечисления
В следующем списке содержатся полезные методы, доступные для перечислений в PowerShell, а также способы их использования.
Формат
Статический Format()
метод возвращает форматированные строковые выходные данные для заданного типа перечисления, значения перечисления и строки форматирования. Выходные данные совпадают с вызовом метода ToString в значении с указанной строкой формата.
Статический метод можно использовать в типе базового класса System.Enum или конкретном типе перечисления.
[System.Enum]::format([<enum-name>], <value>, <format-string>)
[<enum-name>]::format([<enum-name>], <value>, <format-string>)
Допустимые строки форматирования: G
или g
D
, или d
X
, или x
.F
f
Дополнительные сведения см. в разделе "Строки формата перечисления".
В следующем примере каждая из поддерживаемых строк формата перечисления используется для преобразования каждого значения перечисления TaskState в его строковые представления.
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
Метод GetEnumName()
отражения возвращает имя для определенного значения перечисления. Входное значение должно быть допустимым базовым типом для перечисления, например целого числа или значения перечисления. При наличии нескольких имен, связанных со значением, метод возвращает первое определенное имя.
[<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
Метод GetEnumNames()
отражения возвращает имена для каждого значения перечисления в виде строк. Выходные данные включают синонимы.
[<enum-name>].GetEnumNames()
enum Season {
Unknown
Spring
Summer
Autumn
Winter
Fall = 3
}
[Season].GetEnumNames()
Unknown
Spring
Summer
Fall
Autumn
Winter
GetEnumUnderlyingType
Метод GetEnumUnderlyingType()
отражения возвращает базовый тип для значений перечисления.
[<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
Метод отражения возвращает каждое определенное GetEnumValues()
значение для перечисления.
[<enum-name>].GetEnumValues()
enum Season {
Unknown
Spring
Summer
Autumn
Winter
Fall = 3
}
[Season].GetEnumValues()
Unknown
Spring
Summer
Fall
Fall
Winter
GetEnumValuesAsUnderlyingType
Метод GetEnumValuesAsUnderlyingType()
отражения возвращает каждое определенное значение для перечисления в качестве базового типа.
[<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
Метод HasFlag
экземпляра определяет, задан ли битовый флаг для значения перечисления флагов. Использование этого метода проще и проще читать, чем выполнять двоичное сравнение и проверку эквивалентности.
<enum-value>.HasFlag(<enum-flag-value>)
В следующем примере определяется перечисление флага ModuleFeatures и показано, какие флаги имеют значение 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()
метод возвращает $true
, если входное значение определено для перечисления и в противном случае $false
. Используйте этот метод, чтобы проверить, является ли значение допустимым для перечисления без необходимости обрабатывать недопустимые ошибки аргументов.
Статический метод можно использовать в типе базового класса System.Enum или конкретном типе перечисления.
[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
Метод ToString()
экземпляра возвращает метку для значения перечисления.
Этот метод также является представлением по умолчанию о том, как значение перечисления отображается в виде выходных данных. При необходимости можно указать строку формата для управления отображением значения. Дополнительные сведения о форматировании см. в разделе "Форматирование значений перечисления".
Примечание.
Для перечислений, определяющих синонимы для определенного значения, не создавайте код, который зависит от выходных ToString()
данных. Метод может возвращать любое допустимое имя значения.
<enum-value>.ToString([<format-string>])
В следующем примере перечисление шейдера определяется как Gray
синонимGrey
. Затем он выводит объекты, отображающие фактическое значение перечисления, перечисление в виде строки и перечисление в виде целого числа.
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
Синонимы значения перечисления
Вы можете определить перечисления, которые дают разные имена одному целочисленному значению. При этом имена, указывающие на то же базовое значение, называются синонимами. Перечисления с синонимами позволяют пользователям указывать разные имена для одного и того же значения.
При определении перечисления с синонимами не создавайте код, который зависит от значения синонима, преобразующегося в определенное имя. Вы можете надежно написать код, который преобразует строку синонима в значение перечисления. При работе со значением перечисления всегда сравнивайте его как значение перечисления или его базовый тип вместо строки.
Следующий блок кода определяет перечисление шейдера с Grey
синонимами и Gray
как синонимы.
enum Shade {
White
Grey
Gray = 1
Black
}
[Shade]'Grey' -eq [Shade]::Gray
[Shade]::Grey -eq 1
[Shade]'Gray' -eq 1
True
True
True
Перечисления в виде флагов
Одним из распространенных способов перечисления является представление набора взаимоисключающих значений. Например, экземпляр ArrivalStatus может иметь значение early, OnTime или Late. Значение экземпляра ArrivalStatus не имеет смысла отражать несколько констант перечисления.
Однако в других случаях значение объекта перечисления может включать несколько элементов перечисления, а каждый элемент представляет битовое поле в значении перечисления. С помощью FlagsAttribute можно указать, что перечисление состоит из битовых полей в виде флагов, которые пользователи могут объединить.
Для правильной работы перечислений в качестве флагов необходимо задать целочисленное значение каждой метки в качестве двух значений. Если вы не указываете значение для метки, PowerShell задает значение одному выше предыдущей метки.
Вы можете определить значения для часто используемых сочетаний флагов, чтобы упростить для пользователей указание набора флагов одновременно. Имя значения должно быть объединенными именами флагов. Целочисленное значение должно быть суммой значений флага.
Чтобы определить, задан ли определенный флаг для значения, используйте метод по значению или используйте HasFlag()
оператор -band
двоичного сравнения.
Пример использования перечислений флагов и проверки того, задан ли флаг, см . в примере 3.
Перечисления в качестве параметров
Вы можете определить параметры командлета, использующие перечисление в качестве типа. При указании перечисления в качестве типа параметра пользователи получают автоматическое завершение и проверку значения параметра. Завершение аргумента предлагает список допустимых меток для перечисления.
Если параметр имеет перечисление в качестве типа, можно указать любой из:
- Перечисление, например
[<EnumType>]::<Label>
- Метка перечисления в виде строки
- Числовое значение перечисления
Пример, показывающий поведение параметра типа перечисления, см . в примере 4.
Перечисления с определенными базовыми типами
Начиная с PowerShell 6.2, можно определить перечисления с определенным базовым типом. При определении перечисления без определенного базового типа PowerShell создает перечисление с [int]
(System.Int32) в качестве базового типа.
Базовый тип перечисления должен быть целочисленным числовым типом. Следующий список включает допустимые типы с их коротким именем и полным именем типа:
byte
- System.Bytesbyte
- System.SByteshort
- System.Int16ushort
- System.UInt16int
- System.Int32uint
- System.UInt32long
- System.Int64ulong
- System.UInt64
Можно определить конкретный базовый тип перечисления как короткое или полное имя типа. Следующие определения функционально идентичны. Только имя, используемое для базового типа, отличается.
enum LongValueEnum : long {
Zero
One
Two
}
enum LongValueEnum : System.Int64 {
Zero
One
Two
}
Форматирование значений перечисления
Значения перечисления можно преобразовать в их строковые представления, вызвав статический метод Format, а также перегрузки метода ToString экземпляра. Строку форматирования можно использовать для управления точным способом представления значения перечисления в виде строки. Дополнительные сведения см. в разделе "Строки формата перечисления".
В следующем примере для преобразования каждого члена перечисления перечисления в его строковые представления используется каждая из поддерживаемых строк формата перечисления (G
или D
g
, илиd
X
, илиx
F
) f
.
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
В следующем примере строки форматирования используются для значений перечисления флагов.
[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
Обратите внимание, что для перечислений G
флагов строки и F
строки форматирования отображают список флагов набора для значения, разделенного запятыми. Последнее значение, не выводит никаких флагов, 8
так как он не является допустимым набором флагов. Вы не можете объединить флаги перечисления, чтобы получить сумму 8
без дублирования по крайней мере одного флага.
Определение методов расширения с помощью Update-TypeData
Нельзя определить методы в объявлении перечисления. Чтобы расширить функциональные возможности перечисления, можно использовать командлет Update-TypeData для определения ScriptMethod
членов перечисления.
В следующем примере командлет используется Update-TypeData
для добавления GetFlags()
метода в перечисление флага FileAttributes . Он возвращает массив флагов, заданных для значения.
[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
Экспорт перечислений с помощью акселераторов типов
По умолчанию модули PowerShell не экспортируют классы и перечисления, определенные в PowerShell. Пользовательские типы недоступны за пределами модуля без вызова инструкции using module
.
Однако если модуль добавляет акселераторы типов, эти акселераторы типов сразу же доступны в сеансе после импорта модуля.
Примечание.
Добавление акселераторов типов в сеанс использует внутренний (не общедоступный) API. Использование этого API может вызвать конфликты. В приведенном ниже шаблоне возникает ошибка, если акселератор типов с тем же именем уже существует при импорте модуля. Он также удаляет акселераторы типов при удалении модуля из сеанса.
Этот шаблон гарантирует, что типы доступны в сеансе. Это не влияет на IntelliSense или завершение при создании файла скрипта в VS Code.
Чтобы получить предложения IntelliSense и завершения для пользовательских типов в VS Code, необходимо добавить using module
инструкцию в начало скрипта.
В следующем шаблоне показано, как зарегистрировать классы и перечисления PowerShell в качестве акселераторов типов в модуле. Добавьте фрагмент кода в корневой модуль скрипта после определений типов. Убедитесь, $ExportableTypes
что переменная содержит все типы, которые необходимо сделать доступными для пользователей при импорте модуля. Другой код не требует редактирования.
# 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()
При импорте модуля все типы, добавленные в акселераторы типов для сеанса, сразу же доступны для IntelliSense и завершения. При удалении модуля используются акселераторы типов.
Импорт перечислений вручную из модуля PowerShell
Import-Module
#requires
и оператор импортирует только функции модуля, псевдонимы и переменные, как определено модулем. Перечисления не импортируются.
Если модуль определяет классы и перечисления, но не добавляет ускорители типов для этих типов, используйте инструкцию using module
для их импорта.
Инструкция using module
импортирует классы и перечисления из корневого модуля (ModuleToProcess
) модуля скрипта или двоичного модуля. Он не последовательно импортирует классы, определенные в вложенных модулях или классах, определенных в скриптах, которые являются точками источника в корневом модуле. Определите классы, доступные пользователям за пределами модуля непосредственно в корневом модуле.
Дополнительные сведения об инструкции using
см. в about_Using.
Загрузка нового измененного кода во время разработки
Во время разработки модуля скрипта обычно вносятся изменения в код, а затем загружается новая версия модуля с параметром Import-Module
Force . Это работает только для изменений функций в корневом модуле. Import-Module
не перезагрузит вложенные модули. Кроме того, нет способа загрузить обновленные классы.
Чтобы убедиться, что вы используете последнюю версию, необходимо запустить новый сеанс.
Классы и перечисления, определенные в PowerShell и импортированные с помощью инструкции using
, не могут быть выгружены.
Другая распространенная практика разработки заключается в том, чтобы разделить код на разные файлы. Если у вас есть функция в одном файле, в котором используются перечисления, определенные в другом модуле, следует использовать инструкцию using module
, чтобы обеспечить наличие необходимых определений перечисления.
Ограничения
Нельзя декорировать значения перечисления, определенные в PowerShell с атрибутами. Объявление перечисления можно украсить только как с помощью FlagsAttribute для определения перечисления в виде набора битовых флагов.
Обходной путь: нет
Невозможно определить методы внутри определений перечисления, и PowerShell не поддерживает определение [методов расширения], таких как C#.
Обходное решение. Используйте командлет Update-TypeData для определения
ScriptMethod
членов перечисления.
PowerShell