about_Enum

Descripción breve

La enum instrucción declara una enumeración. Una enumeración es un tipo distinto que consta de un conjunto de etiquetas con nombre denominada lista de enumeradores.

Descripción larga

La enum instrucción permite crear un conjunto fuertemente tipado de etiquetas. Puede usar esa enumeración en el código sin tener que analizar ni comprobar si hay errores ortográficos.

Las enumeraciones se representan internamente como tipos de valor entero con un valor inicial de cero. De forma predeterminada, las enumeraciones de PowerShell usan System.Int32 ([int]) como tipo subyacente. De forma predeterminada, PowerShell asigna la primera etiqueta de la lista el valor cero. De forma predeterminada, PowerShell asigna las etiquetas restantes con enteros consecutivos.

En la definición, puede asignar etiquetas a cualquier valor entero. Las etiquetas sin ningún valor asignado toman el siguiente valor entero.

Sintaxis

Las enumeraciones usan las sintaxis siguientes:

Sintaxis de definición de enumeración de enteros

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

Sintaxis de definición de enumeración de tipos subyacentes específica

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

Sintaxis de definición de enumeración de marcas

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

Sintaxis de acceso de enumeración

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

Ejemplos

Ejemplo 1: enumeración mínima

El siguiente bloque de código define la enumeración MarkdownUnorderedListCharacter con tres etiquetas. No asigna valores explícitos a ninguna etiqueta.

enum MarkdownUnorderedListCharacter {
    Asterisk
    Dash
    Plus
}

El siguiente bloque de código muestra cómo se comportan los valores enteros y de cadena cuando se convierten en el tipo de enumeración.

$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

La conversión de enteros que son iguales al valor de una enumeración devuelve esa enumeración. La conversión de cadenas que son iguales que la etiqueta de una enumeración devuelve esa enumeración.

Ejemplo 2: Valores explícitos y de enumeración de sinónimos

En el ejemplo siguiente se muestra una enumeración de objetos que se correlacionan con los archivos multimedia. La definición asigna valores explícitos a los valores subyacentes de music, picture, video. Las etiquetas inmediatamente después de una asignación explícita obtienen el siguiente valor entero. Puede crear sinónimos asignando el mismo valor a otra etiqueta; vea los valores construidos para: ogg, oga, moggo jpgjpeg, o 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
}

El GetEnumNames() método devuelve la lista de etiquetas de la enumeración.

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

El GetEnumValues() método devuelve la lista de los valores de la enumeración.

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

Nota:

GetEnumNames() y GetEnumValues() parecen devolver los mismos resultados; una lista de valores con nombre. Sin embargo, internamente, GetEnumValues() enumera los valores y, a continuación, asigna valores a nombres. Lea cuidadosamente la lista y observará que ogg, ogay mogg aparecen en la salida de GetEnumNames(), pero la salida de GetEnumValues() solo muestra ogg. Lo mismo sucede con jpg, jpegy mpg, mpeg. El nombre que PowerShell devuelve para los valores de sinónimo no es determinista.

Puede usar el GetEnumName() método para obtener un nombre asociado a un valor específico. Si hay varios nombres asociados a un valor, el método devuelve el nombre definido por primera vez.

[MediaTypes].GetEnumName(15)
ogg

En el ejemplo siguiente se muestra cómo asignar cada nombre a su valor.

[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

Puede especificar un único valor de enumeración por su etiqueta con la sintaxis [<enum-name>]::<label>.

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

Ejemplo 3: enumeración como marcas

El siguiente bloque de código crea la enumeración FileAttributes como un conjunto de marcas de bits. El valor de cada etiqueta es el doble del valor de la etiqueta anterior.

[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

Para probar si se establece una marca específica, puede usar el operador -bandde comparación binario . En este ejemplo se comprueban los atributos Device y Archive en el valor de $file2.

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

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

También puede usar el HasFlag() método para probar si se establece una marca específica. En este ejemplo se comprueban los atributos Device y Hidden en el valor de $file1.

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

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

Ejemplo 4: Enumeración como parámetro

En el ejemplo siguiente, la función ConvertTo-LineEndingRegex define el parámetro InputObject con el tipo 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

En el ejemplo, la primera instrucción que llama ConvertTo-LineEndingRegex pasa el valor de enumeración para CR. La segunda instrucción pasa la cadena 'CRLF', que se convierte en lineEnding. La tercera instrucción especifica el valor 2 del parámetro , que se asigna a la LF etiqueta.

Puede ver las opciones de finalización de argumentos escribiendo el texto siguiente en el símbolo del sistema de PowerShell:

ConvertTo-LineEndingRegex -InputObject <Tab>

Al especificar un nombre de etiqueta no válido o un valor numérico para el parámetro , la función genera un error.

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

Ejemplo 5: enumeraciones con tipos subyacentes específicos

A partir de PowerShell 6.2, puede definir enumeraciones con un tipo subyacente específico. En este ejemplo se muestran los tipos subyacentes válidos para una enumeración.

El primer bloque de código inicializa dos variables como matrices. $EnumTypes es una matriz vacía que contiene los tipos creados dinámicamente. $IntegralTypes es una matriz que contiene los tipos subyacentes válidos para una enumeración.

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

El siguiente bloque de código define una plantilla que se usará para crear dinámicamente las definiciones de enumeración. Cuando el {0} marcador de posición de formato se reemplaza por un nombre de tipo entero, la plantilla crea un scriptblock que:

  1. Define una enumeración denominada <type>Enum, como byteEnum. La enumeración definida usa el tipo entero especificado como tipo de valor subyacente.

    La enumeración se define con el Min valor establecido en el valor mínimo para el tipo entero. Define el Max valor establecido en el valor máximo para el tipo entero.

  2. Devuelve el tipo recién definido.

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

[{0}Enum]
"@

El siguiente bloque de código usa la plantilla para crear e invocar un scriptblock en el ámbito actual. Agrega las definiciones de tipo devueltas a la $EnumTypes matriz.

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

El último bloque de código recorre en bucle los tipos de enumeración mediante el GetEnumValuesAsUnderlyingType() método para enumerar los valores como el tipo subyacente. El bucle crea un nuevo objeto para cada valor, que muestra el tipo de enumeración, el tipo de valor, la etiqueta y el valor real.

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

Métodos de enumeración

En la lista siguiente se incluyen métodos útiles disponibles para enumeraciones en PowerShell y cómo usarlos.

Format

El Format() método estático devuelve la salida de cadena con formato para un tipo de enumeración determinado, un valor de enumeración y una cadena de formato. La salida es la misma que llamar al método ToString en el valor con la cadena de formato especificada.

Puede usar el método estático en el tipo de clase base System.Enum o en un tipo de enumeración específico.

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

Las cadenas de formato válidas son G o g, D o X d, o x, y F o f. Para obtener más información, vea Enumeration Format Strings( Cadenas de formato de enumeración).

En el ejemplo siguiente se usa cada una de las cadenas de formato de enumeración admitidas para convertir cada valor de la enumeración TaskState en sus representaciones de cadena.

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

El GetEnumName() método de reflexión devuelve el nombre de un valor de enumeración específico. El valor de entrada debe ser un tipo subyacente válido para una enumeración, como un entero o un valor de enumeración. Si hay varios nombres asociados a un valor, el método devuelve el nombre definido por primera vez.

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

El GetEnumNames() método de reflexión devuelve los nombres de cada valor de enumeración como cadenas. La salida incluye sinónimos.

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

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

GetEnumUnderlyingType

El GetEnumUnderlyingType() método de reflexión devuelve el tipo subyacente para los valores de enumeración.

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

El GetEnumValues() método de reflexión devuelve todos los valores definidos para la enumeración.

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

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

GetEnumValuesAsUnderlyingType

El GetEnumValuesAsUnderlyingType() método de reflexión devuelve todos los valores definidos para la enumeración como el tipo subyacente.

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

El HasFlag método de instancia determina si se establece una marca de bits para un valor de enumeración de marcas. El uso de este método es más corto y fácil de leer que realizar una comparación binaria y una comprobación de equivalencia.

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

En el ejemplo siguiente se define la enumeración de marcas ModuleFeatures y se muestran las marcas que tiene el valor 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

El IsDefined() método estático devuelve $true si el valor de entrada se define para la enumeración y, de lo contrario, $false. Use este método para comprobar si un valor es válido para una enumeración sin necesidad de controlar errores de argumento no válidos.

Puede usar el método estático en el tipo de clase base System.Enum o en un tipo de enumeración específico.

[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

El ToString() método de instancia devuelve la etiqueta de un valor de enumeración. Este método también es la vista predeterminada de cómo se muestra un valor de enumeración como salida. Opcionalmente, puede especificar una cadena de formato para controlar cómo se muestra el valor. Para obtener más información sobre el formato, vea Formato de valores de enumeración.

Nota:

Para las enumeraciones que definen sinónimos para un valor específico, no escriba código que dependa de la salida de ToString(). El método puede devolver cualquier nombre válido para el valor.

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

En el ejemplo siguiente se define la enumeración Shade con Gray como sinónimo de Grey. A continuación, genera objetos que muestran el valor de enumeración real, la enumeración como una cadena y la enumeración como un entero.

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

Sinónimos de valor de enumeración

Puede definir enumeraciones que asignen nombres diferentes al mismo valor entero. Cuando lo hace, los nombres que apuntan al mismo valor subyacente se denominan sinónimos. Las enumeraciones con sinónimos permiten a los usuarios especificar nombres diferentes para el mismo valor.

Al definir una enumeración con sinónimos, no escriba código que dependa de un valor de sinónimo que se convierta en un nombre específico. Puede escribir código de forma confiable que convierta una cadena de sinónimo en el valor de enumeración. Al trabajar con el propio valor de enumeración, compárelo siempre como un valor de enumeración o su tipo subyacente en lugar de como una cadena.

El siguiente bloque de código define la enumeración Shade con Grey y Gray como sinónimos.

enum Shade {
    White
    Grey
    Gray = 1
    Black
}

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

Enumeraciones como marcas

Un uso común de una enumeración es representar un conjunto de valores mutuamente excluyentes. Por ejemplo, una instancia de ArrivalStatus puede tener un valor de Early, OnTime o Late. No tiene sentido que el valor de una instancia de ArrivalStatus refleje más de una constante de enumeración.

Sin embargo, en otros casos, el valor de un objeto de enumeración puede incluir varios miembros de enumeración y cada miembro representa un campo de bits en el valor de enumeración. Puede usar FlagsAttribute para indicar que la enumeración consta de campos de bits como marcas que los usuarios pueden combinar.

Para que las enumeraciones como marcas funcionen correctamente, debe establecer el valor entero de cada etiqueta en una potencia de dos. Si no especifica un valor para una etiqueta, PowerShell establece el valor en uno superior a la etiqueta anterior.

Puede definir valores para combinaciones de marcas usadas habitualmente para facilitar a los usuarios especificar un conjunto de marcas a la vez. El nombre del valor debe ser los nombres combinados de las marcas. El valor entero debe ser la suma de los valores de marca.

Para determinar si se establece una marca específica para un valor, use el HasFlag() método en el valor o use el operador -bandde comparación binario .

Para ver un ejemplo en el que se muestra cómo usar enumeraciones de marcas y comprobar si se establece una marca, vea Ejemplo 3.

Enumeraciones como parámetros

Puede definir parámetros de cmdlet que usen una enumeración como su tipo. Cuando se especifica una enumeración como el tipo de un parámetro, los usuarios obtienen la finalización automática y validación del valor del parámetro. La finalización del argumento sugiere la lista de etiquetas válidas para la enumeración.

Cuando un parámetro tiene una enumeración como su tipo, puede especificar cualquiera de:

  • Una enumeración, como [<EnumType>]::<Label>
  • Etiqueta de una enumeración como una cadena
  • Valor numérico de una enumeración

Para ver un ejemplo que muestra el comportamiento de un parámetro con tipo de enumeración, vea Ejemplo 4.

Enumeraciones con tipos subyacentes específicos

A partir de PowerShell 6.2, puede definir enumeraciones con un tipo subyacente específico. Al definir una enumeración sin un tipo subyacente específico, PowerShell crea la enumeración con [int] (System.Int32) como el tipo subyacente.

El tipo subyacente de una enumeración debe ser un tipo numérico entero. En la lista siguiente se incluyen los tipos válidos con su nombre corto y el nombre de tipo completo:

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

Puede definir un tipo subyacente específico para la enumeración como el nombre corto o el nombre de tipo completo. Las definiciones siguientes son funcionalmente idénticas. Solo el nombre usado para el tipo subyacente es diferente.

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

Aplicar formato a los valores de enumeración

Puede convertir los valores de enumeración en sus representaciones de cadena llamando al método static Format, así como a las sobrecargas del método ToString de instancia. Puede usar una cadena de formato para controlar la forma precisa en que un valor de enumeración se representa como una cadena. Para obtener más información, vea Enumeration Format Strings( Cadenas de formato de enumeración).

En el ejemplo siguiente se usa cada una de las cadenas de formato de enumeración admitidas (G o gD , o d, X o xy F o f ) para convertir cada miembro de la enumeración TaskState en sus representaciones de cadena.

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

En el ejemplo siguiente se usan las cadenas de formato para los valores de una enumeración de marcas.

[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

Observe que para las enumeraciones de marcas, las G cadenas de formato y F muestran la lista de marcas establecidas para el valor delimitado con comas. El último valor, 8, no muestra ninguna marca porque no es realmente un conjunto de marcas válido. No se pueden combinar las marcas de enumeración para obtener una suma de 8 sin duplicar al menos una marca.

Definición de métodos de extensión con Update-TypeData

No se pueden definir métodos en la declaración de una enumeración. Para ampliar la funcionalidad de una enumeración, puede usar el cmdlet Update-TypeData para definir ScriptMethod miembros para la enumeración.

En el ejemplo siguiente se usa el Update-TypeData cmdlet para agregar un GetFlags() método a la enumeración de marcas FileAttributes . Devuelve una matriz de las marcas establecidas para el valor.

[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

Exportación de enumeraciones con aceleradores de tipos

De forma predeterminada, los módulos de PowerShell no exportan automáticamente clases y enumeraciones definidas en PowerShell. Los tipos personalizados no están disponibles fuera del módulo sin llamar a una using module instrucción .

Sin embargo, si un módulo agrega aceleradores de tipos, esos aceleradores de tipos están disponibles inmediatamente en la sesión después de que los usuarios importen el módulo.

Nota:

Agregar aceleradores de tipos a la sesión usa una API interna (no pública). El uso de esta API puede provocar conflictos. El patrón descrito a continuación produce un error si ya existe un acelerador de tipos con el mismo nombre al importar el módulo. También quita los aceleradores de tipos al quitar el módulo de la sesión.

Este patrón garantiza que los tipos están disponibles en una sesión. No afecta a IntelliSense ni a la finalización al crear un archivo de script en VS Code. Para obtener intelliSense y sugerencias de finalización para tipos personalizados en VS Code, debe agregar una using module instrucción a la parte superior del script.

El siguiente patrón muestra cómo puede registrar clases y enumeraciones de PowerShell como aceleradores de tipos en un módulo. Agregue el fragmento de código al módulo de script raíz después de cualquier definición de tipo. Asegúrese de que la $ExportableTypes variable contiene cada uno de los tipos que desea que estén disponibles para los usuarios cuando importen el módulo. El otro código no requiere ninguna edición.

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

Cuando los usuarios importan el módulo, los tipos agregados a los aceleradores de tipos para la sesión están disponibles inmediatamente para IntelliSense y la finalización. Cuando se quita el módulo, por lo que son los aceleradores de tipos.

Importación manual de enumeraciones desde un módulo de PowerShell

Import-Module y la #requires instrucción solo importan las funciones, alias y variables del módulo, tal como se define en el módulo. No se importan las enumeraciones.

Si un módulo define clases y enumeraciones, pero no agrega aceleradores de tipos para esos tipos, use una using module instrucción para importarlas.

La using module instrucción importa clases y enumeraciones desde el módulo raíz (ModuleToProcess) de un módulo de script o un módulo binario. No importa de forma coherente las clases definidas en módulos anidados o clases definidas en scripts con origen de puntos en el módulo raíz. Defina las clases que desea que estén disponibles para los usuarios fuera del módulo directamente en el módulo raíz.

Para obtener más información sobre la using instrucción , consulte about_Using.

Carga del código recién cambiado durante el desarrollo

Durante el desarrollo de un módulo de script, es habitual realizar cambios en el código y, a continuación, cargar la nueva versión del módulo mediante Import-Module con el parámetro Force . Esto funciona solo para los cambios en las funciones del módulo raíz. Import-Module no vuelve a cargar ningún módulo anidado. Además, no hay forma de cargar ninguna clase actualizada.

Para asegurarse de que ejecuta la versión más reciente, debe iniciar una nueva sesión. Las clases y enumeraciones definidas en PowerShell y importadas con una using instrucción no se pueden descargar.

Otra práctica de desarrollo común es separar el código en archivos diferentes. Si tiene una función en un archivo que usa enumeraciones definidas en otro módulo, debe usar la using module instrucción para asegurarse de que las funciones tienen las definiciones de enumeración necesarias.

Limitaciones

  • No se pueden decorar los valores de enumeración definidos en PowerShell con atributos. Solo puede decorar la declaración de enumeración, como con FlagsAttribute para definir una enumeración como un conjunto de marcas de bits.

    Solución alternativa: ninguna

  • No se pueden definir métodos dentro de definiciones de enumeración y PowerShell no admite la definición de [métodos de extensión] como C#.

    Solución alternativa: use el cmdlet Update-TypeData para definir ScriptMethod miembros para la enumeración.