about_Classes_Methods
Descrição breve
Descreve como definir métodos para classes do PowerShell.
Descrição longa
Os métodos definem as ações que uma classe pode executar. Os métodos podem usar parâmetros que especificam dados de entrada. Os métodos sempre definem um tipo de saída. Se um método não retornar nenhuma saída, ele deverá ter o tipo de saída Void . Se um método não definir explicitamente um tipo de saída, o tipo de saída do método será Void.
Nos métodos de classe, nenhum objeto é enviado para o pipeline, exceto aqueles especificados na return
instrução. Não há saída acidental para o pipeline do código.
Observação
Isso é fundamentalmente diferente de como as funções do PowerShell lidam com a saída, em que tudo vai para o pipeline.
Erros de não encerramento gravados no fluxo de erros de dentro de um método de classe não são passados. Você deve usar throw
para exibir um erro de encerramento.
Usando os Write-*
cmdlets, você ainda pode gravar nos fluxos de saída do PowerShell de dentro de um método de classe. Os cmdlets respeitam as variáveis de preferência no escopo de chamada. No entanto, você deve evitar usar os Write-*
cmdlets para que o método gere apenas objetos usando a return
instrução.
Os métodos de classe podem fazer referência à instância atual do objeto de classe usando a $this
variável automática para acessar propriedades e outros métodos definidos na classe atual. A $this
variável automática não está disponível em métodos estáticos.
Os métodos de classe podem ter qualquer número de atributos, incluindo os atributos ocultos e estáticos .
Sintaxe
Os métodos de classe usam as seguintes sintaxes:
Sintaxe unifilar
[[<attribute>]...] [hidden] [static] [<output-type>] <method-name> ([<method-parameters>]) { <body> }
Sintaxe multilinha
[[<attribute>]...]
[hidden]
[static]
[<output-type>] <method-name> ([<method-parameters>]) {
<body>
}
Exemplos
Exemplo 1 - Definição mínima de método
O GetVolume()
método da classe ExampleCube1 retorna o volume do cubo. Ele define o tipo de saída como um número flutuante e retorna o resultado da multiplicação das propriedades Height, Length e Width da instância.
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
Exemplo 2 - Método com parâmetros
O GeWeight()
método usa uma entrada de número flutuante para a densidade do cubo e retorna o peso do cubo, calculado como volume multiplicado pela densidade.
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
Exemplo 3 - Método sem saída
Este exemplo define o Validate()
método com o tipo de saída como System.Void. Esse método não retorna nenhuma saída. Em vez disso, se a validação falhar, ela gerará um erro. O GetVolume()
método chama Validate()
antes de calcular o volume do cubo. Se a validação falhar, o método será encerrado antes do 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.
O método gera uma exceção porque as propriedades Height e Width são inválidas, impedindo que a classe calcule o volume atual.
Exemplo 4 - Método estático com sobrecargas
A classe ExampleCube4 define o método GetVolume()
estático com duas sobrecargas. A primeira sobrecarga tem parâmetros para as dimensões do cubo e um sinalizador para indicar se o método deve validar a entrada.
A segunda sobrecarga inclui apenas as entradas numéricas. Ele chama a primeira sobrecarga com $Static
as .$true
A segunda sobrecarga fornece aos usuários uma maneira de chamar o método sem sempre ter que definir se a entrada deve ser estritamente validada.
A classe também é definida GetVolume()
como um método de instância (não estático). Esse método chama a segunda sobrecarga estática, garantindo que o método de instância GetVolume()
sempre valide as dimensões do cubo antes de retornar o valor de saída.
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.
As mensagens detalhadas nas definições de método mostram como a chamada inicial para $this.GetVolume()
chama o método estático.
Chamando o método estático diretamente com o parâmetro Strict como $false
retorna 0
para o volume.
[ExampleCube4]::GetVolume($Cube.Height, $Cube.Length, $Cube.Width, $false)
VERBOSE: Called [ExampleCube4]::GetVolume(2, 2, 0, False)
0
Assinaturas e sobrecargas de método
Cada método de classe tem uma assinatura exclusiva que define como chamar o método. O tipo de saída, o nome e os parâmetros do método definem a assinatura do método.
Quando uma classe define mais de um método com o mesmo nome, as definições desse método são sobrecargas. As sobrecargas de um método devem ter parâmetros diferentes. Um método não pode definir duas implementações com os mesmos parâmetros, mesmo que os tipos de saída sejam diferentes.
A classe a seguir define dois métodos Shuffle()
e Deal()
. O Deal()
método define duas sobrecargas, uma sem nenhum parâmetro e outra com o 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() })
}
}
Saída do método
Por padrão, os métodos não têm nenhuma saída. Se uma assinatura de método incluir um tipo de saída explícito diferente de Void, o método deverá retornar um objeto desse tipo. Os métodos não emitem nenhuma saída, exceto quando a return
palavra-chave retorna explicitamente um objeto.
Parâmetros de método
Os métodos de classe podem definir parâmetros de entrada a serem usados no corpo do método. Os parâmetros de método estão entre parênteses e separados por vírgulas. Parênteses vazios indicam que o método não requer parâmetros.
Os parâmetros podem ser definidos em uma única linha ou em várias linhas. Os blocos a seguir mostram a sintaxe dos parâmetros do método.
([[<parameter-type>]]$<parameter-name>[, [[<parameter-type>]]$<parameter-name>])
(
[[<parameter-type>]]$<parameter-name>[,
[[<parameter-type>]]$<parameter-name>]
)
Os parâmetros do método podem ser fortemente tipados. Se um parâmetro não for digitado, o método aceitará qualquer objeto para esse parâmetro. Se o parâmetro for digitado, o método tentará converter o valor desse parâmetro para o tipo correto, lançando uma exceção se a entrada não puder ser convertida.
Os parâmetros de método não podem definir valores padrão. Todos os parâmetros do método são obrigatórios.
Os parâmetros de método não podem ter outros atributos. Isso impede que os métodos usem parâmetros com os Validate*
atributos. Para obter mais informações sobre os atributos de validação, consulte about_Functions_Advanced_Parameters.
Você pode usar um dos seguintes padrões para adicionar validação aos parâmetros do método:
- Reatribua os parâmetros às mesmas variáveis com os atributos de validação necessários. Isso funciona para métodos estáticos e de instância. Para obter um exemplo desse padrão, consulte o Exemplo 4.
- Use
Update-TypeData
para definir umScriptMethod
que usa atributos de validação diretamente nos parâmetros. Isso só funciona para métodos de instância. Para obter mais informações, consulte a seção Definindo métodos de instância com Update-TypeData .
Variáveis automáticas em métodos
Nem todas as variáveis automáticas estão disponíveis em métodos. A lista a seguir inclui variáveis automáticas e sugestões sobre se e como usá-las em métodos de classe do PowerShell. As variáveis automáticas não incluídas na lista não estão disponíveis para métodos de classe.
$?
- Acesse normalmente.$_
- Acesse normalmente.$args
- Em vez disso, use as variáveis de parâmetro explícitas.$ConsoleFileName
- Acesse como$Script:ConsoleFileName
.$Error
- Acesse normalmente.$EnabledExperimentalFeatures
- Acesse como$Script:EnabledExperimentalFeatures
.$Event
- Acesse normalmente.$EventArgs
- Acesse normalmente.$EventSubscriber
- Acesse normalmente.$ExecutionContext
- Acesse como$Script:ExecutionContext
.$false
- Acesse normalmente.$foreach
- Acesse normalmente.$HOME
- Acesse como$Script:HOME
.$Host
- Acesse como$Script:Host
.$input
- Em vez disso, use as variáveis de parâmetro explícitas.$IsCoreCLR
- Acesse como$Script:IsCoreCLR
.$IsLinux
- Acesse como$Script:IsLinux
.$IsMacOS
- Acesse como$Script:IsMacOS
.$IsWindows
- Acesse como$Script:IsWindows
.$LASTEXITCODE
- Acesse normalmente.$Matches
- Acesse normalmente.$MyInvocation
- Acesse normalmente.$NestedPromptLevel
- Acesse normalmente.$null
- Acesse normalmente.$PID
- Acesse como$Script:PID
.$PROFILE
- Acesse como$Script:PROFILE
.$PSBoundParameters
- Não use esta variável. Destina-se a cmdlets e funções. Usá-lo em uma aula pode ter efeitos colaterais inesperados.$PSCmdlet
- Não use esta variável. Destina-se a cmdlets e funções. Usá-lo em uma aula pode ter efeitos colaterais inesperados.$PSCommandPath
- Acesse normalmente.$PSCulture
- Acesse como$Script:PSCulture
.$PSEdition
- Acesse como$Script:PSEdition
.$PSHOME
- Acesse como$Script:PSHOME
.$PSItem
- Acesse normalmente.$PSScriptRoot
- Acesse normalmente.$PSSenderInfo
- Acesse como$Script:PSSenderInfo
.$PSUICulture
- Acesse como$Script:PSUICulture
.$PSVersionTable
- Acesse como$Script:PSVersionTable
.$PWD
- Acesse normalmente.$Sender
- Acesse normalmente.$ShellId
- Acesse como$Script:ShellId
.$StackTrace
- Acesse normalmente.$switch
- Acesse normalmente.$this
- Acesse normalmente. Em um método de classe,$this
é sempre a instância atual da classe. Você pode acessar as propriedades e métodos da classe com ele. Ele não está disponível em métodos estáticos.$true
- Acesse normalmente.
Para obter mais informações sobre variáveis automáticas, consulte about_Automatic_Variables.
Métodos ocultos
Você pode ocultar métodos de uma classe declarando-os com a hidden
palavra-chave.
Os métodos de classe oculta são:
- Não incluído na lista de membros da classe retornados pelo
Get-Member
cmdlet. Para mostrar métodos ocultos comGet-Member
, use o parâmetro Force . - Não é exibido na conclusão de tabulação ou no IntelliSense, a menos que a conclusão ocorra na classe que define o método oculto.
- Membros públicos da classe. Eles podem ser chamados e herdados. Ocultar um método não o torna privado. Ele apenas oculta o método conforme descrito nos pontos anteriores.
Observação
Quando você oculta qualquer sobrecarga para um método, esse método é removido do IntelliSense, dos resultados de conclusão e da saída padrão do Get-Member
.
Para obter mais informações sobre a palavra-chave, consulte about_Hiddenhidden
.
Métodos estáticos
Você pode definir um método como pertencente à própria classe em vez de instâncias da classe, declarando o método com a static
palavra-chave. Métodos de classe estática:
- Estão sempre disponíveis, independentemente da instanciação de classe.
- São compartilhados em todas as instâncias da classe.
- Estão sempre disponíveis.
- Não é possível acessar as propriedades de instância da classe. Eles só podem acessar propriedades estáticas.
- Ao vivo durante toda a sessão.
Métodos de classe derivada
Quando uma classe deriva de uma classe base, ela herda os métodos da classe base e suas sobrecargas. Todas as sobrecargas de método definidas na classe base, incluindo métodos ocultos, estão disponíveis na classe derivada.
Uma classe derivada pode substituir uma sobrecarga de método herdada redefinindo-a na definição de classe. Para substituir a sobrecarga, os tipos de parâmetro devem ser os mesmos da classe base. O tipo de saída para a sobrecarga pode ser diferente.
Ao contrário dos construtores, os métodos não podem usar a sintaxe : base(<parameters>)
para invocar uma sobrecarga de classe base para o método. A sobrecarga redefinida na classe derivada substitui completamente a sobrecarga definida pela classe base.
O exemplo a seguir mostra o comportamento de métodos estáticos e de instância em classes derivadas.
A classe base define:
- Os métodos
Now()
estáticos para retornar a hora atual eDaysAgo()
para retornar uma data no passado. - A propriedade de instância TimeStamp e um
ToString()
método de instância que retorna a representação de cadeia de caracteres dessa propriedade. Isso garante que, quando uma instância é usada em uma cadeia de caracteres, ela é convertida na cadeia de caracteres datetime em vez do nome da classe. - O método
SetTimeStamp()
de instância com duas sobrecargas. Quando o método é chamado sem parâmetros, ele define o TimeStamp como a hora atual. Quando o método é chamado com um DateTime, ele define o TimeStamp como esse 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()
}
}
O próximo bloco define classes derivadas de BaseClass:
- DerivedClassA herda de BaseClass sem substituições.
- DerivedClassB substitui o
DaysAgo()
método estático para retornar uma representação de cadeia de caracteres em vez do objeto DateTime . Ele também substitui oToString()
método de instância para retornar o carimbo de data/hora como uma string de data ISO8601. - DerivedClassC substitui a sobrecarga sem parâmetros do método para que a configuração do carimbo de
SetTimeStamp()
data/hora sem parâmetros defina a data como 10 dias antes da data atual.
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))
}
}
O bloco a seguir mostra a saída do método estático Now()
para as classes definidas. A saída é a mesma para todas as classes, pois as classes derivadas não substituem a implementação da classe base do 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
O próximo bloco chama o DaysAgo()
método estático de cada classe. Somente a saída para DerivedClassB é diferente, pois substituiu a implementação 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
O bloco a seguir mostra a apresentação de cadeia de caracteres de uma nova instância para cada classe. A representação de DerivedClassB é diferente porque substituiu o método de ToString()
instância.
"`$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
O próximo bloco chama o método de SetTimeStamp()
instância para cada instância, definindo a propriedade TimeStamp como uma data específica. Cada instância tem a mesma data, pois nenhuma das classes derivadas substitui a sobrecarga parametrizada para o 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
O último bloco chama SetTimeStamp()
sem parâmetros. A saída mostra que o valor da instância DerivedClassC é definido como 10 dias antes dos outros.
"`$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
Definindo métodos de instância com Update-TypeData
Além de declarar métodos diretamente na definição de classe, você pode definir métodos para instâncias de uma classe no construtor estático usando o Update-TypeData
cmdlet.
Use esse snippet como ponto de partida para o padrão. Substitua o texto do espaço reservado entre colchetes angulares, conforme necessário.
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
}
}
}
Dica
O Add-Member
cmdlet pode adicionar propriedades e métodos a uma classe em construtores não estáticos, mas o cmdlet é executado sempre que o construtor é chamado. O uso Update-TypeData
do construtor estático garante que o código para adicionar os membros à classe só precise ser executado uma vez em uma sessão.
Definindo métodos com valores de parâmetro padrão e atributos de validação
Os métodos definidos diretamente em uma declaração de classe não podem definir valores padrão ou atributos de validação nos parâmetros do método. Para definir métodos de classe com valores padrão ou atributos de validação, eles devem ser definidos como membros ScriptMethod .
Neste exemplo, a classe CardDeck define um Draw()
método que usa um atributo de validação e um valor padrão para o 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.
Observação
Embora esse padrão funcione para atributos de validação, observe que a exceção é enganosa, fazendo referência a uma incapacidade de adicionar um atributo. Pode ser uma experiência de usuário melhor verificar explicitamente o valor do parâmetro e gerar um erro significativo. Dessa forma, os usuários podem entender por que estão vendo o erro e o que fazer a respeito.
Limitações
Os métodos de classe do PowerShell têm as seguintes limitações:
Os parâmetros de método não podem usar nenhum atributo, incluindo atributos de validação.
Solução alternativa: reatribua os parâmetros no corpo do método com o atributo de validação ou defina o método no construtor estático com o
Update-TypeData
cmdlet.Os parâmetros de método não podem definir valores padrão. Os parâmetros são sempre obrigatórios.
Solução alternativa: defina o método no construtor estático com o
Update-TypeData
cmdlet.Os métodos são sempre públicos, mesmo quando estão ocultos. Eles podem ser substituídos quando a classe é herdada.
Solução alternativa: Não há.
Se qualquer sobrecarga de um método estiver oculta, todas as sobrecargas desse método também serão tratadas como ocultas.
Solução alternativa: Não há.