about_Enum
简短说明
enum
语句声明枚举。 枚举是一种非重复类型,由一组名为枚举器列表的命名标签组成。
长说明
使用 enum
语句可以创建强类型标签集。 可以在代码中使用该枚举,无需分析或检查拼写错误。
枚举在内部表示为整数值类型,起始值为零。 默认情况下,PowerShell 枚举使用 System.Int32 ([int]
) 作为基础类型。 默认情况下,PowerShell 向列表中的第一个标签分配值“0”。 默认情况下,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()
会枚举这些值,然后将值映射到名称。 仔细阅读列表,你会注意到,ogg
、oga
和 mogg
显示在 GetEnumNames()
的输出中,但 GetEnumValues()
的输出仅显示 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
的值中的 Device 和 Archive 属性进行测试。
PS > ($file2 -band [FileAttributes]::Device) -eq [FileAttributes]::Device
True
PS > ($file2 -band [FileAttributes]::Archive) -eq [FileAttributes]::Archive
False
还可以使用 HasFlag()
方法测试是否设置了特定标志。
此示例针对 $file1
的值中的 Device 和 Hidden 属性进行测试。
PS > $file1.HasFlag([FileAttributes]::Device)
True
PS > $file1.HasFlag([FileAttributes]::Hidden)
False
示例 4 - 枚举作为参数
在以下示例中,ConvertTo-LineEndingRegex
函数使用 EndOfLine 类型定义 InputObject 参数。
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}
格式占位符替换为整型类型名称时,模板将创建一个脚本块,该脚本块:
定义名为 <
a0/&0> 的枚举,例如 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
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()
如果为枚举定义了输入值,则静态方法将返回。否则$false
,静态方法将返回$true
。 使用此方法检查某个值是否对枚举有效,而无需处理无效的参数错误。
可以在 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>])
以下示例将 Shade 枚举 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
同义词的 Shade 枚举。
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 来指示枚举包含位字段作为用户可以组合的标志。
要使枚举作为标志正常工作,必须将每个标签的整数值设置为 2 的幂。 如果未为标签指定值,PowerShell 会将该值设置为高于上一个标签的值。
可以定义常用标志组合的值,以便用户更轻松地同时指定一组标志。 该值的名称应为标志的组合名称。 整数值应为标志值的总和。
若要确定是否为值设置了特定标志,请使用 HasFlag()
该值上的方法或使用二进制比较运算符 -band
。
有关演示如何使用标志枚举并检查是否已设置标志的示例,请参阅 示例 3。
枚举用作参数
可以定义使用枚举作为其类型的 cmdlet 参数。 将枚举指定为参数的类型时,用户可实现参数值的自动补全和验证。 参数补全会建议枚举的有效标签列表。
当参数将枚举用作其类型时,可指定以下任一项:
- 枚举,例如
[<EnumType>]::<Label>
- 用作字符串的枚举的标签
- 枚举的数值
有关显示枚举类型参数行为的示例,请参阅 示例 4。
具有特定基础类型的枚举
从 PowerShell 6.2 开始,可以使用特定的基础类型定义枚举。 在没有特定基础类型的情况下定义枚举时,PowerShell 会创建枚举([int]
System.Int32)作为基础类型。
枚举的基础类型必须是 整型数值类型。 以下列表包括具有其短名称和完整类型名称的有效类型:
byte
- System.Bytesbyte
- System.SByteshort
- System.Int16- System.UInt16
ushort
- int
- System.Int32- System.UInt32
uint
- long
- System.Int64- System.UInt64
ulong
-
可以将枚举的特定基础类型定义为短名称或完整类型名称。 以下定义在功能上是相同的。 只有用于基础类型的名称是不同的。
enum LongValueEnum : long {
Zero
One
Two
}
enum LongValueEnum : System.Int64 {
Zero
One
Two
}
设置枚举值的格式
可以通过调用静态 Format 方法以及实例 ToString 方法的重载将枚举值转换为其字符串表示形式。 可以使用格式字符串来控制枚举值表示为字符串的精确方式。 有关详细信息,请参阅 枚举格式字符串。
以下示例使用每个受支持的枚举格式字符串(G
或g
、D
或d
、X
或,或x
F
或)f
将 TaskState 枚举的每个成员转换为其字符串表示形式。
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 cmdlet 定义 ScriptMethod
枚举的成员。
以下示例使用 Update-TypeData
cmdlet 将方法添加到 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。 使用此 API 可能会导致冲突。 如果导入模块时已存在同名的类型加速器,则下面所述的模式将引发错误。 从会话中删除模块时,它还会删除类型加速器。
此模式可确保类型在会话中可用。 在 VS Code 中创作脚本文件时,它不会影响 IntelliSense 或完成。
若要获取 VS Code 中自定义类型的 IntelliSense 和完成建议,需要将语句添加到 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。
在开发过程中加载新更改的代码
在脚本模块的开发过程中,通常更改代码,然后使用 Force 参数和 Import-Module
加载新版本的模块。 这仅适用于根模块中函数的更改。 Import-Module
不会重新加载任何嵌套模块。 此外,无法加载任何更新的类。
为确保运行最新版本,必须启动新会话。
无法卸载在 PowerShell 中定义并使用 using
语句导入的类和枚举。
另一种常见的开发做法是将代码分成不同的文件。 如果在一个文件中有使用另一个模块中定义的枚举的函数,则应使用 using module
语句来确保函数具有所需的枚举定义。
限制
不能使用属性修饰 PowerShell 中定义的枚举值。 只能修饰枚举声明本身,就像 使用 FlagsAttribute 将枚举定义为一组位标志一样。
解决方法:无
不能在枚举定义中定义方法,PowerShell 不支持定义 [扩展方法] 如 C# 。
解决方法:使用 Update-TypeData cmdlet 定义
ScriptMethod
枚举的成员。