Несколько месяцев назад я написал небольшой скрипт Use-ClassAccessors, чтобы упростить определение методов доступа к классам (геттеров и сеттеров).
Это работает очень хорошо, за исключением небольшого ограничения: сценарий Use-ClassAccessors необходимо вызывать из файла сценария, в котором находится соответствующий класс, чтобы он мог загрузить связанную AST информацию о классе. Неприятный побочный эффект заключается в том, что средства доступа не всегда перезагружаются в модуле¹, над которым я работаю с VSCode. Обходной путь — использовать Kill Terminal и загрузить новый.
psd1 также вызывает скрипт, содержащий класс и функцию Use-ClassAccessors с ScriptsToProcess, но он, очевидно, не перезагружается, когда в сам класс вносятся изменения.Я подозреваю, что смогу решить эту проблему, если смогу запустить функцию Use-ClassAccessors из статического конструктора, как описано здесь.
Дело в том, что я понятия не имею, как мне добраться до исходного кода (AST) самого класса.
Другими словами:
Есть ли способ получить собственный ScriptBlock класса из соответствующего класса, аналогично тому, как я мог бы сделать это в функции:
function GetMyCode {
Write-Host 'My Source Code:'
$MyInvocation.MyCommand.ScriptBlock
}
@MathiasR.Jessen, хорошая мысль, мне нужно кое-что подумать.





Похоже, это проблема XY: на самом деле вам не нужен доступ к исходному коду (или результирующему AST) для обнаружения необходимой информации, вы можете получить ее из результирующего типа во время выполнения:
$targetType = $ClassName -as [Type]
if ($targetType.Assembly.GetName().Name -notmatch 'PowerShell Class Assembly') {
# not a powershell class
return
}
$accessorMethods = $targetType.GetMethods() |? Name -Like "?et_${PropertyName}"
Большое спасибо, я провел несколько быстрых тестов, и действительно похоже, что вся необходимая информация доступна из «статического конструктора» (мне нужно еще немного времени, чтобы переписать мою функцию). @mklement0, этот ответ является хорошим (противным) примером: Что не так с моим ответом?мета-проблема.
@iRon Рад помочь! FWIW «статический конструктор» имеет особое значение во многих .NET-языках (в C# он обычно описывает явный статический инициализатор) — $targetType — это просто экземпляр типа [type] :)
Я не думаю, что для этого вообще нужен доступ к AST — всю необходимую информацию можно извлечь с помощью отражения :)