Infelizmente, não há como parametrizar as propriedades do script. Podemos verificar isso lendo a fonte do PowerShell. Internamente, a contabilidade das propriedades do script é armazenada em PSScriptProperty
objetos. Quando os valores dessas propriedades são solicitados ou alterados, a função privada InvokeGetter
ou InvokeSetter
, respectivamente, é chamada. InvokeSetter
executa o bloco de script setter com o novo valor como o único argumento (como visto na última linha deste trecho):
SetterScript.DoInvokeReturnAsIs(
useLocalScope: true,
errorHandlingBehavior: ScriptBlock.ErrorHandlingBehavior.WriteToExternalErrorPipe,
dollarUnder: AutomationNull.Value,
input: AutomationNull.Value,
scriptThis: scriptThis,
args: new object[] { value });
InvokeGetter
executa o getter script block sem nenhum argumento:
return GetterScript.DoInvokeReturnAsIs(
useLocalScope: true,
errorHandlingBehavior: ScriptBlock.ErrorHandlingBehavior.SwallowErrors,
dollarUnder: AutomationNull.Value,
input: AutomationNull.Value,
scriptThis: scriptThis,
args: Utils.EmptyArray<object>());
Portanto, não podemos passar nenhuma informação extra para o getter ou setter. ( scriptThis
refere-se apenas a $this
, o objeto no qual estamos definindo a propriedade.)
Existe uma solução alternativa: o % cmdletAdd-Type
com o parâmetro -TypeDefinition
. Você pode incorporar algum código C # (ou VB.NET, se preferir) que defina um tipo indexável :
Add-Type -TypeDefinition @"
using System;
using System.Runtime.CompilerServices;
public class SomeClass {
private int[] myArray;
public SomeClass(int Capacity) {
myArray = new int[Capacity];
}
[IndexerName("ArrayData")] public int this[int index] {
get {
Console.WriteLine("Somebody asked for the element at index " + index.ToString() + "!");
return myArray[index];
}
set {
if (value < 0) throw new InvalidOperationException("Negative numbers not allowed");
if (index == 0) throw new InvalidOperationException("The first element cannot be changed");
myArray[index] = value;
}
}
}
"@
Você pode fazer algo assim:
$obj = [SomeClass]::new(5)
$obj[3] = 255
Write-Host $obj[3] # Prints the "somebody accessed" notice, then 255
Ou você pode aproveitar o nome do indexador e fazer isso:
$obj.ArrayData(3) = 255 # Note the parentheses, not brackets
Write-Host $obj.ArrayData(3) # Prints the notice, then 255