น่าเสียดายที่ไม่มีวิธีในการกำหนดค่าคุณสมบัติสคริปต์ เราสามารถตรวจสอบได้โดยการอ่านแหล่งที่มาของ PowerShell ภายในการทำบัญชีคุณสมบัติของสคริปต์จะถูกเก็บไว้ในPSScriptProperty
วัตถุ เมื่อมีการร้องขอหรือแก้ไขค่าของคุณสมบัติดังกล่าวฟังก์ชันส่วนตัวInvokeGetter
หรือInvokeSetter
ตามลำดับจะถูกเรียกใช้ InvokeSetter
รัน setter script block ด้วยค่าใหม่เป็นอาร์กิวเมนต์เท่านั้น (ดังที่เห็นในบรรทัดสุดท้ายของข้อความที่ตัดตอนมานี้):
SetterScript.DoInvokeReturnAsIs(
useLocalScope: true,
errorHandlingBehavior: ScriptBlock.ErrorHandlingBehavior.WriteToExternalErrorPipe,
dollarUnder: AutomationNull.Value,
input: AutomationNull.Value,
scriptThis: scriptThis,
args: new object[] { value });
InvokeGetter
รันบล็อกสคริปต์ getter โดยไม่มีอาร์กิวเมนต์เลย:
return GetterScript.DoInvokeReturnAsIs(
useLocalScope: true,
errorHandlingBehavior: ScriptBlock.ErrorHandlingBehavior.SwallowErrors,
dollarUnder: AutomationNull.Value,
input: AutomationNull.Value,
scriptThis: scriptThis,
args: Utils.EmptyArray<object>());
ดังนั้นเราไม่สามารถส่งข้อมูลพิเศษใด ๆ ไปยังผู้ทะเยอทะยาน ( scriptThis
อ้างถึงเพียง$this
วัตถุที่เราตั้งค่าคุณสมบัติไว้)
มีวิธีแก้ปัญหาคือAdd-Type
cmdlet พร้อม-TypeDefinition
พารามิเตอร์ คุณสามารถฝัง C # (หรือ VB.NET ถ้าคุณต้องการ) รหัสที่กำหนดประเภทที่จัดทำดัชนี :
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;
}
}
}
"@
จากนั้นคุณสามารถทำสิ่งนี้:
$obj = [SomeClass]::new(5)
$obj[3] = 255
Write-Host $obj[3] # Prints the "somebody accessed" notice, then 255
หรือคุณสามารถใช้ประโยชน์จากชื่อตัวทำดัชนีและทำสิ่งนี้:
$obj.ArrayData(3) = 255 # Note the parentheses, not brackets
Write-Host $obj.ArrayData(3) # Prints the notice, then 255