about_Classes_Methods
Descripción breve
Describe cómo definir métodos para las clases de PowerShell.
Descripción larga
Los métodos definen las acciones que una clase puede realizar. Los métodos pueden tomar parámetros que especifican datos de entrada. Los métodos siempre definen un tipo de salida. Si un método no devuelve ninguna salida, debe tener el tipo de salida Void . Si un método no define explícitamente un tipo de salida, el tipo de salida del método es Void.
En los métodos de clase, no se envía ningún objeto a la canalización excepto los especificados en la return
instrucción . No hay ninguna salida accidental en la canalización desde el código.
Nota:
Esto es fundamentalmente diferente de cómo las funciones de PowerShell controlan la salida, donde todo va a la canalización.
Los errores no predeterminados escritos en la secuencia de errores desde dentro de un método de clase no se pasan a través. Debe usar throw
para exponer un error de terminación.
Con los cmdlets, todavía puede escribir en los Write-*
flujos de salida de PowerShell desde dentro de un método de clase. Los cmdlets respetan las variables de preferencia en el ámbito de llamada. Sin embargo, debe evitar usar los Write-*
cmdlets para que el método solo genera objetos mediante la return
instrucción .
Los métodos de clase pueden hacer referencia a la instancia actual del objeto de clase mediante la $this
variable automática para tener acceso a propiedades y otros métodos definidos en la clase actual. La $this
variable automática no está disponible en métodos estáticos.
Los métodos de clase pueden tener cualquier número de atributos, incluidos los atributos ocultos y estáticos .
Sintaxis
Los métodos de clase usan las sintaxis siguientes:
Sintaxis de una línea
[[<attribute>]...] [hidden] [static] [<output-type>] <method-name> ([<method-parameters>]) { <body> }
Sintaxis multilínea
[[<attribute>]...]
[hidden]
[static]
[<output-type>] <method-name> ([<method-parameters>]) {
<body>
}
Ejemplos
Ejemplo 1: definición de método mínima
El GetVolume()
método de la clase ExampleCube1 devuelve el volumen del cubo. Define el tipo de salida como un número flotante y devuelve el resultado de multiplicar las propiedades Height, Length y Width de la instancia.
class ExampleCube1 {
[float] $Height
[float] $Length
[float] $Width
[float] GetVolume() { return $this.Height * $this.Length * $this.Width }
}
$box = [ExampleCube1]@{
Height = 2
Length = 2
Width = 3
}
$box.GetVolume()
12
Ejemplo 2: método con parámetros
El GeWeight()
método toma una entrada de número flotante para la densidad del cubo y devuelve el peso del cubo, calculado como volumen multiplicado por densidad.
class ExampleCube2 {
[float] $Height
[float] $Length
[float] $Width
[float] GetVolume() { return $this.Height * $this.Length * $this.Width }
[float] GetWeight([float]$Density) {
return $this.GetVolume() * $Density
}
}
$cube = [ExampleCube2]@{
Height = 2
Length = 2
Width = 3
}
$cube.GetWeight(2.5)
30
Ejemplo 3: método sin salida
En este ejemplo se define el Validate()
método con el tipo de salida como System.Void. Este método no devuelve ninguna salida. En su lugar, si se produce un error en la validación, se produce un error. El GetVolume()
método llama a Validate()
antes de calcular el volumen del cubo. Si se produce un error en la validación, el método finaliza antes del cálculo.
class ExampleCube3 {
[float] $Height
[float] $Length
[float] $Width
[float] GetVolume() {
$this.Validate()
return $this.Height * $this.Length * $this.Width
}
[void] Validate() {
$InvalidProperties = @()
foreach ($Property in @('Height', 'Length', 'Width')) {
if ($this.$Property -le 0) {
$InvalidProperties += $Property
}
}
if ($InvalidProperties.Count -gt 0) {
$Message = @(
'Invalid cube properties'
"('$($InvalidProperties -join "', '")'):"
"Cube dimensions must all be positive numbers."
) -join ' '
throw $Message
}
}
}
$Cube = [ExampleCube3]@{ Length = 1 ; Width = -1 }
$Cube
$Cube.GetVolume()
Height Length Width
------ ------ -----
0.00 1.00 -1.00
Exception:
Line |
20 | throw $Message
| ~~~~~~~~~~~~~~
| Invalid cube properties ('Height', 'Width'): Cube dimensions must
| all be positive numbers.
El método produce una excepción porque las propiedades Height y Width no son válidas, lo que impide que la clase calcule el volumen actual.
Ejemplo 4: Método estático con sobrecargas
La clase ExampleCube4 define el método GetVolume()
estático con dos sobrecargas. La primera sobrecarga tiene parámetros para las dimensiones del cubo y una marca para indicar si el método debe validar la entrada.
La segunda sobrecarga solo incluye las entradas numéricas. Llama a la primera sobrecarga con $Static
como $true
. La segunda sobrecarga proporciona a los usuarios una manera de llamar al método sin tener que definir siempre si se debe validar estrictamente la entrada.
La clase también define GetVolume()
como un método de instancia (no estático). Este método llama a la segunda sobrecarga estática, asegurándose de que el método de instancia GetVolume()
valida siempre las dimensiones del cubo antes de devolver el valor de salida.
class ExampleCube4 {
[float] $Height
[float] $Length
[float] $Width
static [float] GetVolume(
[float]$Height,
[float]$Length,
[float]$Width,
[boolean]$Strict
) {
$Signature = "[ExampleCube4]::GetVolume({0}, {1}, {2}, {3})"
$Signature = $Signature -f $Height, $Length, $Width, $Strict
Write-Verbose "Called $Signature"
if ($Strict) {
[ValidateScript({$_ -gt 0 })]$Height = $Height
[ValidateScript({$_ -gt 0 })]$Length = $Length
[ValidateScript({$_ -gt 0 })]$Width = $Width
}
return $Height * $Length * $Width
}
static [float] GetVolume([float]$Height, [float]$Length, [float]$Width) {
$Signature = "[ExampleCube4]::GetVolume($Height, $Length, $Width)"
Write-Verbose "Called $Signature"
return [ExampleCube4]::GetVolume($Height, $Length, $Width, $true)
}
[float] GetVolume() {
Write-Verbose "Called `$this.GetVolume()"
return [ExampleCube4]::GetVolume(
$this.Height,
$this.Length,
$this.Width
)
}
}
$VerbosePreference = 'Continue'
$Cube = [ExampleCube4]@{ Height = 2 ; Length = 2 }
$Cube.GetVolume()
VERBOSE: Called $this.GetVolume()
VERBOSE: Called [ExampleCube4]::GetVolume(2, 2, 0)
VERBOSE: Called [ExampleCube4]::GetVolume(2, 2, 0, True)
MetadataError:
Line |
19 | [ValidateScript({$_ -gt 0 })]$Width = $Width
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| The variable cannot be validated because the value 0 is not a valid
| value for the Width variable.
Los mensajes detallados de las definiciones de método muestran cómo la llamada inicial a llama al $this.GetVolume()
método estático.
Llamar al método estático directamente con el parámetro Strict como $false
devuelve 0
para el volumen.
[ExampleCube4]::GetVolume($Cube.Height, $Cube.Length, $Cube.Width, $false)
VERBOSE: Called [ExampleCube4]::GetVolume(2, 2, 0, False)
0
Firmas y sobrecargas del método
Cada método de clase tiene una firma única que define cómo llamar al método . El tipo de salida, el nombre y los parámetros del método definen la firma del método.
Cuando una clase define más de un método con el mismo nombre, las definiciones de ese método son sobrecargas. Las sobrecargas de un método deben tener parámetros diferentes. Un método no puede definir dos implementaciones con los mismos parámetros, incluso si los tipos de salida son diferentes.
La siguiente clase define dos métodos y Shuffle()
Deal()
. El Deal()
método define dos sobrecargas, una sin parámetros y la otra con el parámetro Count .
class CardDeck {
[string[]]$Cards = @()
hidden [string[]]$Dealt = @()
hidden [string[]]$Suits = @('Clubs', 'Diamonds', 'Hearts', 'Spades')
hidden [string[]]$Values = 2..10 + @('Jack', 'Queen', 'King', 'Ace')
CardDeck() {
foreach($Suit in $this.Suits) {
foreach($Value in $this.Values) {
$this.Cards += "$Value of $Suit"
}
}
$this.Shuffle()
}
[void] Shuffle() {
$this.Cards = $this.Cards + $this.Dealt | Where-Object -FilterScript {
-not [string]::IsNullOrEmpty($_)
} | Get-Random -Count $this.Cards.Count
}
[string] Deal() {
if ($this.Cards.Count -eq 0) { throw "There are no cards left." }
$Card = $this.Cards[0]
$this.Cards = $this.Cards[1..$this.Cards.Count]
$this.Dealt += $Card
return $Card
}
[string[]] Deal([int]$Count) {
if ($Count -gt $this.Cards.Count) {
throw "There are only $($this.Cards.Count) cards left."
} elseif ($Count -lt 1) {
throw "You must deal at least 1 card."
}
return (1..$Count | ForEach-Object { $this.Deal() })
}
}
Salida del método
De forma predeterminada, los métodos no tienen ninguna salida. Si una firma de método incluye un tipo de salida explícito distinto de Void, el método debe devolver un objeto de ese tipo. Los métodos no emiten ninguna salida excepto cuando la return
palabra clave devuelve explícitamente un objeto .
Parámetros de métodos
Los métodos de clase pueden definir parámetros de entrada que se usarán en el cuerpo del método. Los parámetros de método se encierran entre paréntesis y se separan por comas. Los paréntesis vacíos indican que el método no requiere parámetros.
Los parámetros se pueden definir en una sola línea o en varias líneas. Los siguientes bloques muestran la sintaxis de los parámetros del método.
([[<parameter-type>]]$<parameter-name>[, [[<parameter-type>]]$<parameter-name>])
(
[[<parameter-type>]]$<parameter-name>[,
[[<parameter-type>]]$<parameter-name>]
)
Los parámetros de método se pueden escribir fuertemente. Si un parámetro no está escrito, el método acepta cualquier objeto para ese parámetro. Si el parámetro está escrito, el método intenta convertir el valor de ese parámetro en el tipo correcto, iniciando una excepción si no se puede convertir la entrada.
Los parámetros del método no pueden definir valores predeterminados. Todos los parámetros de método son obligatorios.
Los parámetros de método no pueden tener ningún otro atributo. Esto impide que los métodos usen parámetros con los Validate*
atributos . Para obtener más información sobre los atributos de validación, consulte about_Functions_Advanced_Parameters.
Puede usar uno de los siguientes patrones para agregar validación a los parámetros del método:
- Reasigna los parámetros a las mismas variables con los atributos de validación necesarios. Esto funciona tanto para métodos estáticos como para instancias. Para obtener un ejemplo de este patrón, vea Ejemplo 4.
- Use
Update-TypeData
para definir unScriptMethod
que use atributos de validación en los parámetros directamente. Esto solo funciona para los métodos de instancia. Para obtener más información, consulte la sección Definición de métodos de instancia con Update-TypeData .
Variables automáticas en métodos
No todas las variables automáticas están disponibles en métodos. En la lista siguiente se incluyen variables automáticas y sugerencias sobre si y cómo usarlas en métodos de clase de PowerShell. Las variables automáticas no incluidas en la lista no están disponibles para los métodos de clase.
$?
- Acceso como normal.$_
- Acceso como normal.$args
: use las variables de parámetro explícitas en su lugar.$ConsoleFileName
- Acceso como$Script:ConsoleFileName
en su lugar.$Error
- Acceso como normal.$EnabledExperimentalFeatures
- Acceso como$Script:EnabledExperimentalFeatures
en su lugar.$Event
- Acceso como normal.$EventArgs
- Acceso como normal.$EventSubscriber
- Acceso como normal.$ExecutionContext
- Acceso como$Script:ExecutionContext
en su lugar.$false
- Acceso como normal.$foreach
- Acceso como normal.$HOME
- Acceso como$Script:HOME
en su lugar.$Host
- Acceso como$Script:Host
en su lugar.$input
: use las variables de parámetro explícitas en su lugar.$IsCoreCLR
- Acceso como$Script:IsCoreCLR
en su lugar.$IsLinux
- Acceso como$Script:IsLinux
en su lugar.$IsMacOS
- Acceso como$Script:IsMacOS
en su lugar.$IsWindows
- Acceso como$Script:IsWindows
en su lugar.$LASTEXITCODE
- Acceso como normal.$Matches
- Acceso como normal.$MyInvocation
- Acceso como normal.$NestedPromptLevel
- Acceso como normal.$null
- Acceso como normal.$PID
- Acceso como$Script:PID
en su lugar.$PROFILE
- Acceso como$Script:PROFILE
en su lugar.$PSBoundParameters
- No use esta variable. Está diseñado para cmdlets y funciones. Usarlo en una clase puede tener efectos secundarios inesperados.$PSCmdlet
- No use esta variable. Está diseñado para cmdlets y funciones. Usarlo en una clase puede tener efectos secundarios inesperados.$PSCommandPath
- Acceso como normal.$PSCulture
- Acceso como$Script:PSCulture
en su lugar.$PSEdition
- Acceso como$Script:PSEdition
en su lugar.$PSHOME
- Acceso como$Script:PSHOME
en su lugar.$PSItem
- Acceso como normal.$PSScriptRoot
- Acceso como normal.$PSSenderInfo
- Acceso como$Script:PSSenderInfo
en su lugar.$PSUICulture
- Acceso como$Script:PSUICulture
en su lugar.$PSVersionTable
- Acceso como$Script:PSVersionTable
en su lugar.$PWD
- Acceso como normal.$Sender
- Acceso como normal.$ShellId
- Acceso como$Script:ShellId
en su lugar.$StackTrace
- Acceso como normal.$switch
- Acceso como normal.$this
- Acceso como normal. En un método de clase,$this
siempre es la instancia actual de la clase . Puede acceder a las propiedades y métodos de clase con él. No está disponible en métodos estáticos.$true
- Acceso como normal.
Para obtener más información sobre las variables automáticas, consulte about_Automatic_Variables.
Métodos ocultos
Puede ocultar métodos de una clase declarandolos con la hidden
palabra clave .
Los métodos de clase ocultos son:
- No se incluye en la lista de miembros de clase devueltos por el
Get-Member
cmdlet . Para mostrar métodos ocultos conGet-Member
, use el parámetro Force . - No se muestra en la finalización de tabulación o IntelliSense a menos que se produzca la finalización en la clase que define el método oculto.
- Miembros públicos de la clase . Se pueden llamar y heredar. Ocultar un método no lo hace privado. Solo oculta el método como se describe en los puntos anteriores.
Nota:
Al ocultar cualquier sobrecarga de un método, ese método se quita de IntelliSense, los resultados de finalización y la salida predeterminada para Get-Member
.
Para obtener más información sobre la hidden
palabra clave , consulte about_Hidden.
Métodos estáticos
Puede definir un método como perteneciente a la propia clase en lugar de las instancias de la clase declarando el método con la static
palabra clave . Métodos de clase estáticos:
- Siempre están disponibles, independientemente de la creación de instancias de clase.
- Se comparten en todas las instancias de la clase .
- Siempre están disponibles.
- No se puede acceder a las propiedades de instancia de la clase . Solo pueden acceder a propiedades estáticas.
- Live para todo el intervalo de sesión.
Métodos de clase derivados
Cuando una clase se deriva de una clase base, hereda los métodos de la clase base y sus sobrecargas. Las sobrecargas de método definidas en la clase base, incluidos los métodos ocultos, están disponibles en la clase derivada.
Una clase derivada puede invalidar una sobrecarga de método heredado redefinirla en la definición de clase. Para invalidar la sobrecarga, los tipos de parámetro deben ser los mismos que para la clase base. El tipo de salida de la sobrecarga puede ser diferente.
A diferencia de los constructores, los métodos no pueden usar la : base(<parameters>)
sintaxis para invocar una sobrecarga de clase base para el método . La sobrecarga redefinida de la clase derivada reemplaza completamente la sobrecarga definida por la clase base.
En el ejemplo siguiente se muestra el comportamiento de los métodos estáticos y de instancia en las clases derivadas.
La clase base define:
- Los métodos estáticos
Now()
para devolver la hora actual yDaysAgo()
para devolver una fecha en el pasado. - La propiedad de instancia TimeStamp y un
ToString()
método de instancia que devuelve la representación de cadena de esa propiedad. Esto garantiza que, cuando se usa una instancia en una cadena, se convierte en la cadena datetime en lugar del nombre de clase. - Método de instancia
SetTimeStamp()
con dos sobrecargas. Cuando se llama al método sin parámetros, establece timeStamp en la hora actual. Cuando se llama al método con dateTime, establece timeStamp en ese valor.
class BaseClass {
static [datetime] Now() {
return Get-Date
}
static [datetime] DaysAgo([int]$Count) {
return [BaseClass]::Now().AddDays(-$Count)
}
[datetime] $TimeStamp = [BaseClass]::Now()
[string] ToString() {
return $this.TimeStamp.ToString()
}
[void] SetTimeStamp([datetime]$TimeStamp) {
$this.TimeStamp = $TimeStamp
}
[void] SetTimeStamp() {
$this.TimeStamp = [BaseClass]::Now()
}
}
El siguiente bloque define las clases derivadas de BaseClass:
- DerivedClassA hereda de BaseClass sin invalidaciones.
- DerivedClassB invalida el
DaysAgo()
método estático para devolver una representación de cadena en lugar del objeto DateTime . También invalida elToString()
método de instancia para devolver la marca de tiempo como una cadena de fecha ISO8601. - DerivedClassC invalida la sobrecarga sin parámetros del
SetTimeStamp()
método para que establecer la marca de tiempo sin parámetros establezca la fecha en 10 días antes de la fecha actual.
class DerivedClassA : BaseClass {}
class DerivedClassB : BaseClass {
static [string] DaysAgo([int]$Count) {
return [BaseClass]::DaysAgo($Count).ToString('yyyy-MM-dd')
}
[string] ToString() {
return $this.TimeStamp.ToString('yyyy-MM-dd')
}
}
class DerivedClassC : BaseClass {
[void] SetTimeStamp() {
$this.SetTimeStamp([BaseClass]::Now().AddDays(-10))
}
}
En el bloque siguiente se muestra la salida del método estático Now()
para las clases definidas. La salida es la misma para cada clase, ya que las clases derivadas no invalidan la implementación de clase base del método .
"[BaseClass]::Now() => $([BaseClass]::Now())"
"[DerivedClassA]::Now() => $([DerivedClassA]::Now())"
"[DerivedClassB]::Now() => $([DerivedClassB]::Now())"
"[DerivedClassC]::Now() => $([DerivedClassC]::Now())"
[BaseClass]::Now() => 11/06/2023 09:41:23
[DerivedClassA]::Now() => 11/06/2023 09:41:23
[DerivedClassB]::Now() => 11/06/2023 09:41:23
[DerivedClassC]::Now() => 11/06/2023 09:41:23
El siguiente bloque llama al DaysAgo()
método estático de cada clase. Solo la salida de DerivedClassB es diferente, ya que sobrepone la implementación base.
"[BaseClass]::DaysAgo(3) => $([BaseClass]::DaysAgo(3))"
"[DerivedClassA]::DaysAgo(3) => $([DerivedClassA]::DaysAgo(3))"
"[DerivedClassB]::DaysAgo(3) => $([DerivedClassB]::DaysAgo(3))"
"[DerivedClassC]::DaysAgo(3) => $([DerivedClassC]::DaysAgo(3))"
[BaseClass]::DaysAgo(3) => 11/03/2023 09:41:38
[DerivedClassA]::DaysAgo(3) => 11/03/2023 09:41:38
[DerivedClassB]::DaysAgo(3) => 2023-11-03
[DerivedClassC]::DaysAgo(3) => 11/03/2023 09:41:38
En el bloque siguiente se muestra la presentación de cadena de una nueva instancia para cada clase. La representación de DerivedClassB es diferente porque sobrepone el ToString()
método de instancia.
"`$base = [BaseClass]::New() => $($base = [BaseClass]::New(); $base)"
"`$a = [DerivedClassA]::New() => $($a = [DerivedClassA]::New(); $a)"
"`$b = [DerivedClassB]::New() => $($b = [DerivedClassB]::New(); $b)"
"`$c = [DerivedClassC]::New() => $($c = [DerivedClassC]::New(); $c)"
$base = [BaseClass]::New() => 11/6/2023 9:44:57 AM
$a = [DerivedClassA]::New() => 11/6/2023 9:44:57 AM
$b = [DerivedClassB]::New() => 2023-11-06
$c = [DerivedClassC]::New() => 11/6/2023 9:44:57 AM
El siguiente bloque llama al SetTimeStamp()
método de instancia para cada instancia, estableciendo la propiedad TimeStamp en una fecha específica. Cada instancia tiene la misma fecha, ya que ninguna de las clases derivadas invalida la sobrecarga parametrizada para el método .
[datetime]$Stamp = '2024-10-31'
"`$base.SetTimeStamp(`$Stamp) => $($base.SetTimeStamp($Stamp) ; $base)"
"`$a.SetTimeStamp(`$Stamp) => $($a.SetTimeStamp($Stamp); $a)"
"`$b.SetTimeStamp(`$Stamp) => $($b.SetTimeStamp($Stamp); $b)"
"`$c.SetTimeStamp(`$Stamp) => $($c.SetTimeStamp($Stamp); $c)"
$base.SetTimeStamp($Stamp) => 10/31/2024 12:00:00 AM
$a.SetTimeStamp($Stamp) => 10/31/2024 12:00:00 AM
$b.SetTimeStamp($Stamp) => 2024-10-31
$c.SetTimeStamp($Stamp) => 10/31/2024 12:00:00 AM
El último bloque llama SetTimeStamp()
sin parámetros. La salida muestra que el valor de la instancia de DerivedClassC se establece en 10 días antes de los demás.
"`$base.SetTimeStamp() => $($base.SetTimeStamp() ; $base)"
"`$a.SetTimeStamp() => $($a.SetTimeStamp(); $a)"
"`$b.SetTimeStamp() => $($b.SetTimeStamp(); $b)"
"`$c.SetTimeStamp() => $($c.SetTimeStamp(); $c)"
$base.SetTimeStamp() => 11/6/2023 9:53:58 AM
$a.SetTimeStamp() => 11/6/2023 9:53:58 AM
$b.SetTimeStamp() => 2023-11-06
$c.SetTimeStamp() => 10/27/2023 9:53:58 AM
Definición de métodos de instancia con Update-TypeData
Más allá de declarar métodos directamente en la definición de clase, puede definir métodos para instancias de una clase en el constructor estático mediante el Update-TypeData
cmdlet .
Use este fragmento de código como punto de partida para el patrón. Reemplace el texto del marcador de posición entre corchetes angulares según sea necesario.
class <ClassName> {
static [hashtable[]] $MemberDefinitions = @(
@{
MemberName = '<MethodName>'
MemberType = 'ScriptMethod'
Value = {
param(<method-parameters>)
<method-body>
}
}
)
static <ClassName>() {
$TypeName = [<ClassName>].Name
foreach ($Definition in [<ClassName>]::MemberDefinitions) {
Update-TypeData -TypeName $TypeName @Definition
}
}
}
Sugerencia
El Add-Member
cmdlet puede agregar propiedades y métodos a una clase en constructores no estáticos, pero el cmdlet se ejecuta cada vez que se llama al constructor. El uso Update-TypeData
de en el constructor estático garantiza que el código para agregar los miembros a la clase solo debe ejecutarse una vez en una sesión.
Definición de métodos con valores de parámetro predeterminados y atributos de validación
Los métodos definidos directamente en una declaración de clase no pueden definir valores predeterminados ni atributos de validación en los parámetros del método. Para definir métodos de clase con valores predeterminados o atributos de validación, deben definirse como miembros ScriptMethod .
En este ejemplo, la clase CardDeck define un Draw()
método que usa un atributo de validación y un valor predeterminado para el parámetro Count .
class CookieJar {
[int] $Cookies = 12
static [hashtable[]] $MemberDefinitions = @(
@{
MemberName = 'Eat'
MemberType = 'ScriptMethod'
Value = {
param(
[ValidateScript({ $_ -ge 1 -and $_ -le $this.Cookies })]
[int] $Count = 1
)
$this.Cookies -= $Count
if ($Count -eq 1) {
"You ate 1 cookie. There are $($this.Cookies) left."
} else {
"You ate $Count cookies. There are $($this.Cookies) left."
}
}
}
)
static CookieJar() {
$TypeName = [CookieJar].Name
foreach ($Definition in [CookieJar]::MemberDefinitions) {
Update-TypeData -TypeName $TypeName @Definition
}
}
}
$Jar = [CookieJar]::new()
$Jar.Eat(1)
$Jar.Eat()
$Jar.Eat(20)
$Jar.Eat(6)
You ate 1 cookie. There are 11 left.
You ate 1 cookie. There are 10 left.
MethodInvocationException:
Line |
36 | $Jar.Eat(20)
| ~~~~~~~~~~~~
| Exception calling "Eat" with "1" argument(s): "The attribute
| cannot be added because variable Count with value 20 would no
| longer be valid."
You ate 6 cookies. There are 4 left.
Nota:
Aunque este patrón funciona para los atributos de validación, observe que la excepción es engañosa, haciendo referencia a una incapacidad para agregar un atributo. Puede ser una mejor experiencia de usuario para comprobar explícitamente el valor del parámetro y generar un error significativo en su lugar. De este modo, los usuarios pueden comprender por qué ven el error y qué hacer sobre él.
Limitaciones
Los métodos de clase de PowerShell tienen las siguientes limitaciones:
Los parámetros de método no pueden usar ningún atributo, incluidos los atributos de validación.
Solución alternativa: vuelva a asignar los parámetros en el cuerpo del método con el atributo de validación o defina el método en el constructor estático con el
Update-TypeData
cmdlet .Los parámetros del método no pueden definir valores predeterminados. Los parámetros siempre son obligatorios.
Solución alternativa: defina el método en el constructor estático con el
Update-TypeData
cmdlet .Los métodos siempre son públicos, incluso cuando están ocultos. Se pueden invalidar cuando se hereda la clase .
Solución alternativa: Ninguna.
Si alguna sobrecarga de un método está oculta, todas las sobrecargas de ese método también se tratan como ocultas.
Solución alternativa: Ninguna.