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 - 明確和同義字列舉值

下列範例顯示與媒體檔案相互關聯的 物件列舉。 定義會將明確值指派給、 picturevideo的基礎值music。 緊接在明確指派之後的標籤會取得下一個整數值。 您可以將相同的值指派給另一個標籤,以建立同義字;請參閱下列項目的建構值:ogg、、moggoga、 或 jpgjpeg、 或 mpgmpeg

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() 列舉值,然後將值對應至名稱。 請仔細閱讀清單,您會發現 oggogamogg 會顯示在 輸出 GetEnumNames()中,但的 GetEnumValues() 輸出只會顯示 ogg。 、 jpegmpgmpeg會發生jpg相同的情況。 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。 此範例會測試 的 DeviceArchive 屬性的值 $file2

PS > ($file2 -band [FileAttributes]::Device) -eq [FileAttributes]::Device
True

PS > ($file2 -band [FileAttributes]::Archive) -eq [FileAttributes]::Archive
False

您也可以使用 HasFlag() 方法來測試是否已設定特定旗標。 此範例會測試的值中的 $file1DeviceHidden 屬性。

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。 第三個語句會指定對應至卷LF標的參數值2

您可以在 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}當格式佔位元取代為整數類型名稱時,範本區塊,以:

  1. 定義名為 <type>Enum的列舉,例如 byteEnum。 定義的列舉會使用指定的整數型別做為基礎實值型別。

    列舉是使用設定為整數型別最小值的值來定義 Min 。 它會定義 Max 設定為整數型別最大值的值。

  2. 傳回新定義的型別。

$DefinitionTemplate = @"
enum {0}Enum : {0} {{
    Min = [{0}]::MinValue
    Max = [{0}]::MaxValue
}}

[{0}Enum]
"@

下一個程式代碼區塊會使用範本,在目前範圍內建立及叫用 scriptblock。 它會將傳回的類型定義 $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>)

有效的格式字串為 GgDdX 、 或 xFf或 。 如需詳細資訊,請參閱 列舉格式字串

下列範例會使用每個支援的列舉格式字串,將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>])

下列範例會將 的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

列舉值同義字

您可以定義列舉,為相同的整數值提供不同的名稱。 當您這樣做時,指向相同基礎值的名稱稱為 同義字。 具有同義字的列舉可讓使用者為相同的值指定不同的名稱。

當您使用同義字定義列舉時,請勿撰寫相依於轉換成特定名稱的同義字值的程序代碼。 您可以可靠地撰寫將同義字字串轉換成列舉值的程式代碼。 使用列舉值本身時,請一律將其比較為列舉值或其基礎類型,而不是做為字串。

下列程式代碼區塊會使用 和 Gray 定義 Shade 列舉Grey作為同義字。

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

列舉作為參數

您可以定義使用列舉作為其類型的 Cmdlet 參數。 當您將列舉指定為參數的類型時,用戶會自動完成參數的值和驗證。 自變數完成會建議列舉的有效標籤清單。

當參數具有列舉作為其類型時,您可以指定下列任一專案:

  • 列舉,例如 [<EnumType>]::<Label>
  • 列舉為字串的標籤
  • 列舉的數值

如需顯示列舉型別參數行為的範例,請參閱 範例 4

具有特定基礎類型的列舉

從 PowerShell 6.2 開始,您可以使用特定的基礎類型來定義列舉。 當您定義不含特定基礎類型的列舉時,PowerShell 會使用 (System.Int32) 建立列舉[int]做為基礎類型。

列舉的基礎類型必須是 整數數值類型。 下列清單包含其簡短名稱和完整類型名稱的有效類型:

  • byte - System.Byte
  • sbyte - System.SByte
  • short - System.Int16
  • ushort - System.UInt16
  • int - System.Int32
  • uint - System.UInt32
  • long - System.Int64
  • ulong - System.UInt64

您可以將列舉的特定基礎類型定義為簡短名稱或完整類型名稱。 下列定義在功能上完全相同。 只有基礎類型所使用的名稱不同。

enum LongValueEnum : long {
    Zero
    One
    Two
}
enum LongValueEnum : System.Int64 {
    Zero
    One
    Two
}

格式化列舉值

您可以呼叫靜態 Format 方法,以及實例 ToString 方法的多載,將列舉值轉換成其字串表示法。 您可以使用格式字串來控制列舉值以字串表示的精確方式。 如需詳細資訊,請參閱 列舉格式字串

下列範例會使用每個支援的列舉格式字串 (G或、 DgdX 、 或 xF 或或 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

請注意,針對旗標列舉, GF 格式字串會顯示以逗號分隔之值的設定旗標清單。 最後一個值 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 可能會導致衝突。 如果您匯入模組時已有相同名稱的類型加速器存在,以下所述的模式會擲回錯誤。 當您從會話中移除模組時,它也會移除類型加速器。

此模式可確保類型可在會話中使用。 在 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 列舉的成員。