Bagikan melalui


about_Enum

Deskripsi singkat

Pernyataan menyatakan enum enumerasi. Enumerasi adalah jenis berbeda yang terdiri dari sekumpulan label bernama yang disebut daftar enumerator.

Deskripsi panjang

Pernyataan ini enum memungkinkan Anda membuat sekumpulan label yang sangat ditik. Anda dapat menggunakan enumerasi tersebut dalam kode tanpa harus mengurai atau memeriksa kesalahan ejaan.

Enumerasi secara internal diwakili sebagai jenis nilai integral dengan nilai awal nol. Secara default, enumerasi PowerShell menggunakan System.Int32 ([int]) sebagai jenis yang mendasar. Secara default, PowerShell menetapkan label pertama dalam daftar nilai nol. Secara default, PowerShell menetapkan label yang tersisa dengan bilangan bulat berturut-turut.

Dalam definisi, Anda dapat memberikan label nilai bilangan bulat apa pun. Label tanpa nilai yang ditetapkan mengambil nilai bilangan bulat berikutnya.

Sintaks

Enumerasi menggunakan sintaks berikut:

Sintaks definisi enumerasi bilangan bulat

[[<attribute>]...] enum <enum-name> {
    <label> [= <int-value>]
    ...
}

Sintaks definisi enumerasi jenis dasar tertentu

[[<attribute>]...] enum <enum-name> : <underlying-type-name> {
    <label> [= <int-value>]
    ...
}

Sintaks definisi enumerasi bendera

[[<attribute>]...] [Flag()] enum <enum-name>[ : <underlying-type-name>] {
    <label 0> [= 1]
    <label 1> [= 2]
    <label 2> [= 4]
    <label 3> [= 8]
    ...
    ...
}

Sintaks akses enumerasi

[<enum-name>]::<label>

Contoh

Contoh 1 - Enumerasi minimal

Blok kode berikut mendefinisikan enumerasi MarkdownUnorderedListCharacter dengan tiga label. Ini tidak menetapkan nilai eksplisit ke label apa pun.

enum MarkdownUnorderedListCharacter {
    Asterisk
    Dash
    Plus
}

Blok kode berikutnya menunjukkan bagaimana nilai bilangan bulat dan string berperilaku saat ditransmisikan ke jenis enumerasi.

$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

Melemparkan bilangan bulat yang sama dengan nilai enumerasi mengembalikan enumerasi tersebut. String casting yang sama dengan label enumerasi mengembalikan enumerasi tersebut.

Contoh 2 - Nilai enumerasi eksplisit dan sinonim

Contoh berikut menunjukkan enumerasi objek yang berkorelasi dengan file media. Definisi menetapkan nilai eksplisit ke nilai yang mendasar dari music, , videopicture. Label segera setelah penetapan eksplisit mendapatkan nilai bilangan bulat berikutnya. Anda dapat membuat sinonim dengan menetapkan nilai yang sama ke label lain; lihat nilai yang dibangun untuk: ogg, , oga, moggatau jpg, jpeg, atau 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
}

Metode mengembalikan GetEnumNames() daftar label untuk enumerasi.

[MediaTypes].GetEnumNames()
unknown
music
mp3
aac
ogg
oga
mogg
picture
jpg
jpeg
png
video
mpg
mpeg
avi
m4v

Metode GetEnumValues() mengembalikan daftar nilai untuk enumerasi.

[MediaTypes].GetEnumValues()
unknown
music
mp3
aac
ogg
ogg
ogg
picture
jpg
jpg
png
video
mpg
mpg
avi
m4v

Catatan

GetEnumNames() dan GetEnumValues() tampaknya mengembalikan hasil yang sama; daftar nilai bernama. Namun, secara internal, GetEnumValues() menghitung nilai, lalu memetakan nilai menjadi nama. Baca daftar dengan hati-hati dan Anda akan melihat bahwa ogg, oga, dan mogg muncul dalam output GetEnumNames(), tetapi output hanya GetEnumValues() menunjukkan ogg. Hal yang sama terjadi untuk jpg, , jpegdan mpg, mpeg. Nama yang ditampilkan PowerShell untuk nilai sinonim tidak deterministik.

Anda dapat menggunakan GetEnumName() metode untuk mendapatkan nama yang terkait dengan nilai tertentu. Jika ada beberapa nama yang terkait dengan nilai, metode mengembalikan nama pertama yang ditentukan.

[MediaTypes].GetEnumName(15)
ogg

Contoh berikut menunjukkan cara memetakan setiap nama ke nilainya.

[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

Anda dapat menentukan nilai enum tunggal dengan labelnya dengan sintaks [<enum-name>]::<label>.

[MediaTypes]::png
[MediaTypes]::png -eq 22
png
True

Contoh 3 - Enumerasi sebagai bendera

Blok kode berikut membuat enumerasi FileAttributes sebagai sekumpulan bendera bit. Nilai untuk setiap label adalah dua kali lipat dari nilai label sebelumnya.

[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

Untuk menguji apakah bendera tertentu diatur, Anda dapat menggunakan operator -bandperbandingan biner . Contoh ini menguji untuk Perangkat dan atribut Arsip dalam nilai $file2.

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

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

Anda juga dapat menggunakan HasFlag() metode untuk menguji apakah bendera tertentu diatur. Contoh ini menguji atribut Perangkat dan Tersembunyi dalam nilai $file1.

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

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

Contoh 4 - Enumerasi sebagai parameter

Dalam contoh berikut, fungsi ConvertTo-LineEndingRegex menentukan parameter InputObject dengan jenis 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

Dalam contoh, pernyataan pertama yang memanggil ConvertTo-LineEndingRegex melewati nilai enumerasi untuk CR. Pernyataan kedua meneruskan string 'CRLF', yang ditransmisikan ke LineEnding. Pernyataan ketiga menentukan nilai 2 untuk parameter, yang memetakan ke LF label.

Anda dapat melihat opsi penyelesaian argumen dengan mengetikkan teks berikut ke dalam perintah PowerShell Anda:

ConvertTo-LineEndingRegex -InputObject <Tab>

Saat Anda menentukan nama label atau nilai numerik yang tidak valid untuk parameter, fungsi akan menimbulkan kesalahan.

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".

Contoh 5 - Enumerasi dengan jenis mendasar tertentu

Mulai dari PowerShell 6.2, Anda dapat menentukan enumerasi dengan jenis mendasar tertentu. Contoh ini menunjukkan jenis yang mendasar yang valid untuk enumerasi.

Blok kode pertama menginisialisasi dua variabel sebagai array. $EnumTypes adalah array kosong untuk menyimpan jenis yang dibuat secara dinamis. $IntegralTypes adalah array yang berisi jenis yang mendasar yang valid untuk enumerasi.

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

Blok kode berikutnya mendefinisikan templat yang akan digunakan untuk membuat definisi enumerasi secara dinamis. {0} Saat tempat penampung format diganti dengan nama jenis integral, templat membuat blokir skrip yang:

  1. Mendefinisikan enumerasi bernama <type>Enum, seperti byteEnum. Enumerasi yang ditentukan menggunakan jenis integral yang ditentukan sebagai jenis nilai yang mendasar.

    Enumerasi didefinisikan dengan nilai yang Min diatur ke nilai minimum untuk jenis integral. Ini mendefinisikan nilai yang Max diatur ke nilai maksimum untuk jenis integral.

  2. Mengembalikan jenis yang baru ditentukan.

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

[{0}Enum]
"@

Blok kode berikutnya menggunakan templat untuk membuat dan memanggil blokir skrip dalam cakupan saat ini. Ini menambahkan definisi jenis yang dikembalikan ke $EnumTypes dalam array.

foreach ($IntegralType in $IntegralTypes) {
    $Definition  = $DefinitionTemplate -f $IntegralType
    $ScriptBlock = [scriptblock]::Create($Definition)
    $EnumTypes  += . $ScriptBlock
}

Blok kode terakhir mengulangi jenis enum, menggunakan GetEnumValuesAsUnderlyingType() metode untuk mencantumkan nilai sebagai jenis yang mendasar. Perulangan membuat objek baru untuk setiap nilai, memperlihatkan jenis enumerasi, jenis nilai, label, dan nilai aktual.

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

Metode enumerasi

Daftar berikut ini mencakup metode berguna yang tersedia untuk enumerasi di PowerShell dan cara menggunakannya.

Format

Metode Format() statis mengembalikan output string yang diformat untuk jenis enumerasi tertentu, nilai enumerasi, dan string format. Outputnya sama dengan memanggil metode ToString pada nilai dengan string format yang ditentukan.

Anda dapat menggunakan metode statis pada jenis kelas dasar System.Enum atau jenis enumerasi tertentu.

[System.Enum]::format([<enum-name>], <value>, <format-string>)
[<enum-name>]::format([<enum-name>], <value>, <format-string>)

String format yang valid adalah atau , atau , atau , dan F atau f.xX dD gG Untuk informasi selengkapnya, lihat String Format Enumerasi.

Contoh berikut menggunakan setiap string format enumerasi yang didukung untuk mengonversi setiap nilai enumerasi TaskState ke representasi stringnya.

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

Metode GetEnumName() refleksi mengembalikan nama untuk nilai enumerasi tertentu. Nilai input harus merupakan jenis yang mendasar yang valid untuk enumerasi, seperti bilangan bulat, atau nilai enumerasi. Jika ada beberapa nama yang terkait dengan nilai, metode mengembalikan nama pertama yang ditentukan.

[<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

Metode GetEnumNames() pantulan mengembalikan nama untuk setiap nilai enumerasi sebagai string. Output mencakup sinonim.

[<enum-name>].GetEnumNames()
enum Season {
    Unknown
    Spring
    Summer
    Autumn
    Winter
    Fall   = 3
}

[Season].GetEnumNames()
Unknown
Spring
Summer
Fall
Autumn
Winter

GetEnumUnderlyingType

Metode GetEnumUnderlyingType() refleksi mengembalikan jenis yang mendasar untuk nilai enumerasi.

[<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

Metode GetEnumValues() refleksi mengembalikan setiap nilai yang ditentukan untuk enumerasi.

[<enum-name>].GetEnumValues()
enum Season {
    Unknown
    Spring
    Summer
    Autumn
    Winter
    Fall   = 3
}

[Season].GetEnumValues()
Unknown
Spring
Summer
Fall
Fall
Winter

GetEnumValuesAsUnderlyingType

Metode GetEnumValuesAsUnderlyingType() refleksi mengembalikan setiap nilai yang ditentukan untuk enumerasi sebagai jenis yang mendasar.

[<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

Metode HasFlag instans menentukan apakah bendera bit diatur untuk nilai enumerasi bendera. Menggunakan metode ini lebih pendek dan lebih mudah dibaca daripada melakukan perbandingan biner dan pemeriksaan kesetaraan.

<enum-value>.HasFlag(<enum-flag-value>)

Contoh berikut mendefinisikan enumerasi bendera ModuleFeatures dan menunjukkan bendera mana yang memiliki nilai 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

Metode IsDefined() statis mengembalikan $true jika nilai input ditentukan untuk enumerasi dan sebaliknya $false. Gunakan metode ini untuk memeriksa apakah nilai valid untuk enumerasi tanpa perlu menangani kesalahan argumen yang tidak valid.

Anda dapat menggunakan metode statis pada jenis kelas dasar System.Enum atau jenis enumerasi tertentu.

[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

Metode ToString() instans mengembalikan label untuk nilai enumerasi. Metode ini juga merupakan tampilan default untuk bagaimana nilai enumerasi ditampilkan sebagai output. Secara opsional, Anda dapat menentukan string format untuk mengontrol bagaimana nilai ditampilkan. Untuk informasi selengkapnya tentang pemformatan, lihat Memformat nilai enumerasi.

Catatan

Untuk enumerasi yang menentukan sinonim untuk nilai tertentu, jangan tulis kode yang bergantung pada output .ToString() Metode ini dapat mengembalikan nama yang valid untuk nilai tersebut.

<enum-value>.ToString([<format-string>])

Contoh berikut mendefinisikan enumerasi Bayangan dengan Gray sebagai sinonim untuk Grey. Kemudian menghasilkan objek yang menunjukkan nilai enum aktual, enum sebagai string, dan enum sebagai bilangan bulat.

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

Sinonim nilai enumerasi

Anda dapat menentukan enumerasi yang memberikan nama yang berbeda ke nilai bilangan bulat yang sama. Ketika Anda melakukannya, nama yang menunjuk ke nilai dasar yang sama disebut sinonim. Enumerasi dengan sinonim memungkinkan pengguna menentukan nama yang berbeda untuk nilai yang sama.

Saat Anda menentukan enumerasi dengan sinonim, jangan tulis kode yang bergantung pada nilai sinonim yang mengonversi ke nama tertentu. Anda dapat menulis kode dengan andal yang mengonversi string sinonim ke nilai enumerasi. Saat bekerja dengan nilai enumerasi itu sendiri, selalu bandingkan sebagai nilai enumerasi atau jenis yang mendasarnya alih-alih sebagai string.

Blok kode berikut mendefinisikan enumerasi Bayangan dengan Grey dan Gray sebagai sinonim.

enum Shade {
    White
    Grey
    Gray = 1
    Black
}

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

Enumerasi sebagai bendera

Salah satu penggunaan umum enumerasi adalah mewakili sekumpulan nilai yang saling eksklusif. Misalnya, instans ArrivalStatus dapat memiliki nilai Awal, OnTime, atau Terlambat. Tidak masuk akal bagi nilai instans ArrivalStatus untuk mencerminkan lebih dari satu konstanta enumerasi.

Namun, dalam kasus lain, nilai objek enumerasi dapat mencakup beberapa anggota enumerasi, dan setiap anggota mewakili bidang bit dalam nilai enumerasi. Anda dapat menggunakan FlagsAttribute untuk menunjukkan bahwa enumerasi terdiri dari bidang bit sebagai bendera yang dapat digabungkan pengguna.

Agar enumerasi sebagai bendera berfungsi dengan baik, Anda harus mengatur nilai bilangan bulat setiap label ke kekuatan dua. Jika Anda tidak menentukan nilai untuk label, PowerShell mengatur nilai ke nilai yang lebih tinggi dari label sebelumnya.

Anda dapat menentukan nilai untuk kombinasi bendera yang umum digunakan untuk memudahkan pengguna menentukan sekumpulan bendera sekaligus. Nama untuk nilai harus berupa nama gabungan dari bendera. Nilai bilangan bulat harus berupa jumlah nilai bendera.

Untuk menentukan apakah bendera tertentu diatur untuk nilai, gunakan HasFlag() metode pada nilai atau gunakan operator -bandperbandingan biner .

Untuk sampel yang menunjukkan cara menggunakan enumerasi bendera dan memeriksa apakah bendera diatur, lihat Contoh 3.

Enumerasi sebagai parameter

Anda dapat menentukan parameter cmdlet yang menggunakan enum sebagai jenisnya. Saat Anda menentukan enum sebagai jenis untuk parameter, pengguna mendapatkan penyelesaian otomatis untuk dan validasi nilai parameter. Penyelesaian argumen menyarankan daftar label yang valid untuk enum.

Saat parameter memiliki enum sebagai jenisnya, Anda dapat menentukan salah satu dari:

  • Enumerasi, seperti [<EnumType>]::<Label>
  • Label untuk enumerasi sebagai string
  • Nilai numerik dari enumerasi

Untuk sampel yang menunjukkan perilaku parameter yang dititik enumerasi, lihat Contoh 4.

Enumerasi dengan jenis yang mendasar tertentu

Mulai dari PowerShell 6.2, Anda dapat menentukan enumerasi dengan jenis mendasar tertentu. Saat Anda menentukan enumerasi tanpa jenis dasar tertentu, PowerShell membuat enumerasi dengan [int] (System.Int32) sebagai jenis yang mendasar.

Jenis yang mendasar untuk enumerasi harus merupakan jenis numerik integral. Daftar berikut ini menyertakan jenis yang valid dengan nama pendek dan nama jenis lengkapnya:

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

Anda dapat menentukan jenis dasar tertentu untuk enumerasi sebagai nama pendek atau nama jenis lengkap. Definisi berikut secara fungsional identik. Hanya nama yang digunakan untuk jenis yang mendasar yang berbeda.

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

Nilai enumerasi pemformatan

Anda dapat mengonversi nilai enumerasi ke representasi string mereka dengan memanggil metode Format statis, serta kelebihan beban metode ToString instans. Anda dapat menggunakan string format untuk mengontrol cara yang tepat di mana nilai enumerasi diwakili sebagai string. Untuk informasi selengkapnya, lihat String Format Enumerasi.

Contoh berikut menggunakan setiap string format enumerasi yang didukung ( atau ,G atau g, D atau xd, X dan atau F f ) untuk mengonversi setiap anggota enumerasi TaskState ke representasi stringnya.

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

Contoh berikut menggunakan string format untuk nilai enumerasi bendera.

[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

Perhatikan bahwa untuk enumerasi bendera, G string format dan F menampilkan daftar bendera yang ditetapkan untuk nilai yang dibatasi dengan koma. Nilai terakhir, 8, tidak mencantumkan bendera apa pun karena sebenarnya bukan set bendera yang valid. Anda tidak dapat menggabungkan bendera enumerasi untuk mendapatkan jumlah tanpa menduplikasi 8 setidaknya satu bendera.

Menentukan metode ekstensi dengan Update-TypeData

Anda tidak dapat menentukan metode dalam deklarasi untuk enumerasi. Untuk memperluas fungsionalitas enumerasi, Anda dapat menggunakan cmdlet Update-TypeData untuk menentukan ScriptMethod anggota enumerasi.

Contoh berikut menggunakan Update-TypeData cmdlet untuk menambahkan GetFlags() metode ke enumerasi bendera FileAttributes . Ini mengembalikan array bendera yang ditetapkan untuk nilai .

[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

Mengekspor enumerasi dengan jenis akselerator

Secara default, modul PowerShell tidak secara otomatis mengekspor kelas dan enumerasi yang ditentukan di PowerShell. Jenis kustom tidak tersedia di luar modul tanpa memanggil using module pernyataan.

Namun, jika modul menambahkan akselerator jenis, akselerator jenis tersebut segera tersedia dalam sesi setelah pengguna mengimpor modul.

Catatan

Menambahkan akselerator jenis ke sesi menggunakan API internal (bukan publik). Menggunakan API ini dapat menyebabkan konflik. Pola yang dijelaskan di bawah ini melemparkan kesalahan jika akselerator jenis dengan nama yang sama sudah ada saat Anda mengimpor modul. Ini juga menghapus jenis akselerator saat Anda menghapus modul dari sesi.

Pola ini memastikan bahwa jenis tersedia dalam sesi. Ini tidak memengaruhi IntelliSense atau penyelesaian saat menulis file skrip di Visual Studio Code. Untuk mendapatkan saran IntelliSense dan penyelesaian untuk jenis kustom di Visual Studio Code, Anda perlu menambahkan using module pernyataan ke bagian atas skrip.

Pola berikut menunjukkan bagaimana Anda dapat mendaftarkan kelas dan enumerasi PowerShell sebagai akselerator jenis dalam modul. Tambahkan cuplikan ke modul skrip akar setelah definisi jenis apa pun. Pastikan $ExportableTypes variabel berisi setiap jenis yang ingin Anda sediakan untuk pengguna saat mengimpor modul. Kode lain tidak memerlukan pengeditan apa pun.

# 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()

Saat pengguna mengimpor modul, jenis apa pun yang ditambahkan ke akselerator jenis untuk sesi segera tersedia untuk IntelliSense dan penyelesaian. Ketika modul dihapus, begitu juga akselerator jenis.

Mengimpor enumerasi secara manual dari modul PowerShell

Import-Module#requires dan pernyataan hanya mengimpor fungsi modul, alias, dan variabel, seperti yang didefinisikan oleh modul. Enumerasi tidak diimpor.

Jika modul mendefinisikan kelas dan enumerasi tetapi tidak menambahkan akselerator jenis untuk jenis tersebut, gunakan using module pernyataan untuk mengimpornya.

Pernyataan mengimpor using module kelas dan enumerasi dari modul akar (ModuleToProcess) modul skrip atau modul biner. Ini tidak secara konsisten mengimpor kelas yang ditentukan dalam modul atau kelas berlapis yang ditentukan dalam skrip yang bersumber titik ke dalam modul akar. Tentukan kelas yang ingin Anda sediakan untuk pengguna di luar modul langsung di modul akar.

Untuk informasi selengkapnya tentang pernyataan tersebut using , lihat about_Using.

Memuat kode yang baru diubah selama pengembangan

Selama pengembangan modul skrip, umumnya untuk membuat perubahan pada kode lalu memuat versi baru modul menggunakan Import-Module dengan parameter Force . Ini hanya berfungsi untuk perubahan pada fungsi dalam modul akar. Import-Module tidak memuat ulang modul berlapis apa pun. Selain itu, tidak ada cara untuk memuat kelas yang diperbarui.

Untuk memastikan bahwa Anda menjalankan versi terbaru, Anda harus memulai sesi baru. Kelas dan enumerasi yang ditentukan di PowerShell dan diimpor dengan using pernyataan tidak dapat dibongkar.

Praktik pengembangan umum lainnya adalah memisahkan kode Anda ke dalam file yang berbeda. Jika Anda memiliki fungsi dalam satu file yang menggunakan enumerasi yang ditentukan dalam modul lain, Anda harus menggunakan using module pernyataan untuk memastikan bahwa fungsi memiliki definisi enumerasi yang diperlukan.

Batasan

  • Anda tidak dapat menghias nilai enumerasi yang ditentukan di PowerShell dengan atribut. Anda hanya dapat menghias deklarasi enumerasi itu sendiri, seperti halnya FlagsAttribute untuk menentukan enumerasi sebagai sekumpulan bendera bit.

    Solusi sementara: Tidak ada

  • Anda tidak dapat menentukan metode di dalam definisi enumerasi dan PowerShell tidak mendukung penentuan [metode ekstensi] seperti C#.

    Solusi sementara: Gunakan cmdlet Update-TypeData untuk menentukan ScriptMethod anggota untuk enumerasi.