次の方法で共有


about_Enum

簡単な説明

ステートメントは enum 列挙体を宣言します。 列挙体は、列挙子リストと呼ばれる名前付きラベルのセットで構成される個別の型です。

長い説明

enumステートメントを使用すると、厳密に型指定されたラベルのセットを作成できます。 コード内でその列挙を使用すると、スペル ミスを解析したりチェックしたりする必要はありません。

列挙体は、開始値が 0 の整数値型として内部的に表されます。 既定では、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 列挙を 3 つのラベルで定義します。 どのラベルにも明示的な値は割り当てられません。

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 - 明示的な列挙値とシノニム列挙値

次の例は、メディア ファイルに関連付けるオブジェクトの列挙を示しています。 定義は、 の基になる値に明示的な値musicpicturevideoを割り当てます。 明示的な割り当ての直後のラベルは、次の整数値を取得します。 同じ値を別のラベルに割り当てることで、シノニムを作成できます。、、、jpegjpgまたは mpgmpegの構築された値ogaoggmoggを参照してください。

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、、 ogamogg が の出力に表示されますが、 の出力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 列挙を ビット フラグのセットとして作成します。 各ラベルの値は、前のラベルの値の 2 倍です。

[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を使用します。 この例では、 の値$file2Device 属性と Archive 属性をテストします。

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

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

メソッドを使用して、特定の HasFlag() フラグが設定されているかどうかをテストすることもできます。 この例では、 の値$file1Device 属性と Hidden 属性をテストします。

PS > $file1.HasFlag([FileAttributes]::Device)
True

PS > $file1.HasFlag([FileAttributes]::Hidden)
False

例 4 - パラメーターとしての列挙

次の例では、関数ConvertTo-LineEndingRegexEndOfLine 型の 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渡します。 2 番目のステートメントは、LineEnding にキャストされる文字列 'CRLF'を渡します。 3 番目のステートメントは、ラベルにマップされる パラメーターの値 2LF 指定します。

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 以降では、特定の基になる型を使用して列挙を定義できます。 この例では、列挙型の有効な基になる型を示します。

最初のコード ブロックは、2 つの変数を配列として初期化します。 $EnumTypes は、動的に作成された型を保持する空の配列です。 $IntegralTypes は、列挙型の有効な基になる型を含む配列です。

$EnumTypes     = @()
$IntegralTypes = @(
    'byte', 'sbyte', 'short', 'ushort', 'int', 'uint', 'long', 'ulong'
)

次のコード ブロックでは、列挙定義を動的に作成するために使用するテンプレートを定義します。 書式プレースホルダーが {0} 整数型名に置き換えられると、テンプレートによって次のスクリプト ブロックが作成されます。

  1. のような byteEnumという名前<type>Enumの列挙体を定義します。 定義された列挙では、指定した整数型を基になる値型として使用します。

    列挙型は、整数型の 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>)

有効な書式指定文字列は、Gまたは gDXd、、xFまたは です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>])

次の例では、 のノニムGreyとして を使用して Gray Shade 列挙体を定義します。 次に、実際の列挙型の値、列挙型を文字列として、列挙型を整数として示すオブジェクトを出力します。

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 をシノニムとして使用して Grey Shade 列挙を定義します。

enum Shade {
    White
    Grey
    Gray = 1
    Black
}

[Shade]'Grey' -eq [Shade]::Gray
[Shade]::Grey -eq 1
[Shade]'Gray' -eq 1
True
True
True

フラグとしての列挙

列挙型の一般的な用途の 1 つは、相互に排他的な値のセットを表すことです。 たとえば、 ArrivalStatus インスタンスの値は Early、OnTime、Late のいずれかです。 ArrivalStatus インスタンスの値が複数の列挙定数を反映することは意味がありません。

ただし別の場合、列挙オブジェクトの値には複数の列挙体メンバーを含めることができ、各メンバーは列挙値のビットフィールドを表します。 FlagsAttribute を使用して、列挙体が、ユーザーが組み合わせることができるフラグとしてビット フィールドで構成されていることを示すことができます。

フラグとしての列挙を正しく機能させるには、各ラベルの整数値を 2 の累乗に設定する必要があります。 ラベルの値を指定しない場合、PowerShell は値を前のラベルより 1 高い値に設定します。

一般的に使用されるフラグの組み合わせの値を定義して、ユーザーが一度にフラグのセットを簡単に指定できるようにすることができます。 値の名前は、フラグの組み合わせ名にする必要があります。 整数値は、フラグ値の合計である必要があります。

値に対して特定のフラグが設定されているかどうかを判断するには、値に対して メソッドを HasFlag() 使用するか、バイナリ比較演算子 を使用します -band

フラグ列挙を使用し、フラグが設定されているかどうかをチェックする方法を示すサンプルについては、「例 3」を参照してください。

パラメーターとしての列挙

列挙型を型として使用するコマンドレット パラメーターを定義できます。 列挙型をパラメーターの型として指定すると、ユーザーはパラメーターの値の自動入力候補と検証を受け取ります。 引数の入力候補は、列挙型の有効なラベルの一覧を示します。

パラメーターの型として列挙型がある場合は、次のいずれかを指定できます。

  • 列挙型 (例: ) [<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 または gD 、または dX 、 または xFf ) を使用して、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

フラグ列挙の場合、 および F 書式指定文字列には、Gコンマで区切られた値のセット フラグの一覧が表示されます。 最後の値 である は、 8実際には有効なフラグ セットではないので、フラグを一覧表示しません。 少なくとも 1 つのフラグを複製せずに列挙フラグを結合して の 8 合計を取得することはできません。

Update-TypeData を使用した拡張メソッドの定義

列挙型の宣言でメソッドを定義することはできません。 列挙体の機能を拡張するには、 Update-TypeData コマンドレットを使用して、列挙型のメンバーを定義 ScriptMethod できます。

次の例では、 コマンドレットをUpdate-TypeData使用して、FileAttributes フラグ列挙にメソッドを追加GetFlags()します。 値に設定されたフラグの配列を返します。

[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 インポートされたクラスと列挙はアンロードできません。

もう 1 つの一般的な開発方法は、コードを異なるファイルに分割することです。 あるファイルに別のモジュールで定義された列挙型を使用する関数がある場合は、 ステートメントを using module 使用して、関数に必要な列挙定義があることを確認する必要があります。

制限事項

  • PowerShell で定義されている列挙値を属性で装飾することはできません。 列挙体をビット フラグのセットとして定義するために FlagsAttribute と同様に、列挙宣言自体のみを装飾できます。

    回避策: ありません。

  • 列挙定義内でメソッドを定義することはできません。また、PowerShell では C# のような [拡張メソッド] の定義はサポートされていません。

    回避策: Update-TypeData コマンドレットを使用して、列挙体のメンバーを定義 ScriptMethod します。