O PowerShell oferece suporte a scripts de validação para variáveis. Isso é mais comumente usado para validar parâmetros de função, mas pode ser aplicado a qualquer variável. Esses scripts de validação são executados sempre que o valor da variável é alterado.
# create a variable with a validation script
[ValidateScript({
if (-not ($_.Length -in @(8, 16, 24))) {
Write-Host 'Validate Failed'
throw "Value '$_' has invalid length: $($_.Length)"
} else {
Write-Host 'Validate Success'
}
$true
})][System.String]$MyValidatedArg = "a" * 8 # prints "Validate Success"
# Each one of these will trigger the validation script
Write-Host "Several valid assignments..."
$MyValidatedArg = "b" * 8 # prints "Validate Success"
$MyValidatedArg = "b" * 8 # prints "Validate Success"
$MyValidatedArg = "b" * 16 # prints "Validate Success"
$MyValidatedArg = "b" * 24 # prints "Validate Success"
Se eu atribuísse um valor inválido à variável, isso geraria uma exceção
$MyValidatedArg = "foo" # throws an exception
Estranhamente, consigo ignorar o script de validação se eu especificar novamente a restrição de tipo durante a atribuição. Sei que "simplesmente não faça isso" é uma opção, mas o ponto principal da minha pergunta é: por que isso funciona?
[System.String]$MyValidatedArg = "123456789" # works even though this value is invalid
A princípio, pensei que fosse apenas um sombreamento de variáveis. Tipo, talvez eu estivesse criando uma segunda variável, objeto ou algo assim, especificando a restrição de tipo uma segunda vez. Tentei capturar uma referência à variável para ver se ela manteria o script de validação. Não mantém, mas não estou muito familiarizado com os detalhes internos do PowerShell para saber se este é um teste válido.
# create a reference and assign through the reference
Write-Host "Assigning through reference..."
$refToParameter = [ref] $MyValidatedArg
$refToParameter.Value = "c" * 24 # prints "Validate Success"
Write-Host " Read via variable: $MyValidatedArg"
Write-Host " Read via reference: $($refToParameter.Value)"
# the reference and the variable are linked
# Assignments to either trigger the validation script
Write-Host "Assigning through normal variable again..."
$MyValidatedArg = "d" * 24 # prints "Validate Success"
Write-Host " Read via variable: $MyValidatedArg"
Write-Host " Read via reference: $($refToParameter.Value)"
# This works, which is odd
Write-Host "Assigning with [System.String]..."
[System.String]$MyValidatedArg = "123456789" # invalid, nothing printed
Write-Host " No exceptions yet!"
# I thought this was some sort of variable shadowing thing, but the reference shows the new value too
Write-Host "The link between the variable and the reference is still there..."
$MyValidatedArg = "e" * 8 # valid, nothing printed
Write-Host " Read via variable: $MyValidatedArg"
Write-Host " Read via reference: $($refToParameter.Value)"
# and now we appear to have killed the validation script
Write-Host "Regular invalid assignment..."
$MyValidatedArg = "123456789" # invalid, nothing printed
Write-Host " It works now for some reason"