about_Classes_Methods
Breve descrição
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 deve 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.
Em 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 a partir do código.
Nota
Isso é fundamentalmente diferente de como as funções do PowerShell lidam com a saída, onde tudo vai para o pipeline.
Os erros não terminativos 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 produza 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 de uma linha
[[<attribute>]...] [hidden] [static] [<output-type>] <method-name> ([<method-parameters>]) { <body> }
Sintaxe de várias linhas
[[<attribute>]...]
[hidden]
[static]
[<output-type>] <method-name> ([<method-parameters>]) {
<body>
}
Exemplos
Exemplo 1 - Definição mínima do 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. Este método não retorna nenhuma saída. Em vez disso, se a validação falhar, ele lança um erro. O GetVolume()
método chama Validate()
antes de calcular o volume do cubo. Se a validação falhar, o método termina 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 lança 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 de $Static
como $true
. A segunda sobrecarga dá aos usuários uma maneira de chamar o método sem sempre ter que definir se deseja validar estritamente a entrada.
A classe também define 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.
Chamar o método estático diretamente com o parâmetro Strict como $false
retornos 0
para o volume.
[ExampleCube4]::GetVolume($Cube.Height, $Cube.Length, $Cube.Width, $false)
VERBOSE: Called [ExampleCube4]::GetVolume(2, 2, 0, False)
0
Assinaturas de método e sobrecargas
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 para 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 quaisquer parâmetros 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 inclui um tipo de saída explícito diferente de Void, o método deve 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 do método
Os métodos de classe podem definir parâmetros de entrada para usar no corpo do método. Os parâmetros do método são colocados 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 do método não podem definir valores padrão. Todos os parâmetros do método são obrigatórios.
Os parâmetros do 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, por exemplo, métodos. 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 nos 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 os métodos de classe.
$?
- Acesso normalmente.$_
- Acesso normalmente.$args
- Em vez disso, use as variáveis de parâmetros explícitos.$ConsoleFileName
- Acesso como$Script:ConsoleFileName
em vez disso.$Error
- Acesso normalmente.$EnabledExperimentalFeatures
- Acesso como$Script:EnabledExperimentalFeatures
em vez disso.$Event
- Acesso normalmente.$EventArgs
- Acesso normalmente.$EventSubscriber
- Acesso normalmente.$ExecutionContext
- Acesso como$Script:ExecutionContext
em vez disso.$false
- Acesso normalmente.$foreach
- Acesso normalmente.$HOME
- Acesso como$Script:HOME
em vez disso.$Host
- Acesso como$Script:Host
em vez disso.$input
- Em vez disso, use as variáveis de parâmetros explícitos.$IsCoreCLR
- Acesso como$Script:IsCoreCLR
em vez disso.$IsLinux
- Acesso como$Script:IsLinux
em vez disso.$IsMacOS
- Acesso como$Script:IsMacOS
em vez disso.$IsWindows
- Acesso como$Script:IsWindows
em vez disso.$LASTEXITCODE
- Acesso normalmente.$Matches
- Acesso normalmente.$MyInvocation
- Acesso normalmente.$NestedPromptLevel
- Acesso normalmente.$null
- Acesso normalmente.$PID
- Acesso como$Script:PID
em vez disso.$PROFILE
- Acesso como$Script:PROFILE
em vez disso.$PSBoundParameters
- Não utilize esta variável. Destina-se a cmdlets e funções. Usá-lo em uma classe pode ter efeitos colaterais inesperados.$PSCmdlet
- Não utilize esta variável. Destina-se a cmdlets e funções. Usá-lo em uma classe pode ter efeitos colaterais inesperados.$PSCommandPath
- Acesso normalmente.$PSCulture
- Acesso como$Script:PSCulture
em vez disso.$PSEdition
- Acesso como$Script:PSEdition
em vez disso.$PSHOME
- Acesso como$Script:PSHOME
em vez disso.$PSItem
- Acesso normalmente.$PSScriptRoot
- Acesso normalmente.$PSSenderInfo
- Acesso como$Script:PSSenderInfo
em vez disso.$PSUICulture
- Acesso como$Script:PSUICulture
em vez disso.$PSVersionTable
- Acesso como$Script:PSVersionTable
em vez disso.$PWD
- Acesso normalmente.$Sender
- Acesso normalmente.$ShellId
- Acesso como$Script:ShellId
em vez disso.$StackTrace
- Acesso normalmente.$switch
- Acesso normalmente.$this
- Acesso normalmente. Em um método de classe,$this
é sempre a instância atual da classe. Você pode acessar as propriedades e os métodos da classe com ele. Não está disponível em métodos estáticos.$true
- Acesso 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 ocultos são:
- Não incluído na lista de membros de classe retornados pelo
Get-Member
cmdlet. Para mostrar métodos ocultos comGet-Member
, use o parâmetro Force . - Não é exibido no preenchimento 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 turma. Podem ser chamados e herdados. Ocultar um método não o torna privado. Apenas oculta o método descrito nos pontos anteriores.
Nota
Quando você oculta qualquer sobrecarga para um método, esse método é removido do IntelliSense, resultados de conclusão e a saída padrão para Get-Member
.
Para obter mais informações sobre a hidden
palavra-chave, consulte about_Hidden.
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 da classe.
- São compartilhados em todas as instâncias da classe.
- Estão sempre disponíveis.
- Não é possível acessar as propriedades da instância da classe. Eles só podem acessar propriedades estáticas.
- Ao vivo durante toda a duração da sessão.
Métodos de classe derivados
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 : base(<parameters>)
sintaxe 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 para 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 para a 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 para a hora atual. Quando o método é chamado com um DateTime, ele define o TimeStamp para 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 cadeia de caracteres de data ISO8601. - DerivedClassC substitui a sobrecarga sem parâmetros do
SetTimeStamp()
método para que a configuração do carimbo de 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, porque 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. Apenas a saída para DerivedClassB é diferente, porque 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 para DerivedClassB é diferente porque substituiu o ToString()
método de 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 para uma data específica. Cada instância tem a mesma data, porque 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 quaisquer parâmetros. A saída mostra que o valor para a 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 este trecho 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
}
}
}
Gorjeta
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. Usar Update-TypeData
no construtor estático garante que o código para adicionar os membros à classe só precisa ser executado uma vez em uma sessão.
Definindo métodos com valores de parâmetros 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.
Nota
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 do 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 validation ou defina o método no construtor estático com o
Update-TypeData
cmdlet.Os parâmetros do 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 escondidos. Eles podem ser substituídos quando a classe é herdada.
Alternativa: nenhuma.
Se qualquer sobrecarga de um método estiver oculta, cada sobrecarga para esse método será tratada como oculta também.
Alternativa: nenhuma.