Вызов методов на переданном объекте - PullRequest
1 голос
/ 19 апреля 2019

Было бы хорошо иметь фильтр PS для вызова метода, такого как

[System.Text.Encoding]::UTF8.GetString

сделать возможным что-то вроде:

filter Invoke-Method { ... ?? ... }

Invoke-WebRequest $url `
    | Select-Object Content `
    | Invoke-Method [System.Text.Encoding]::UTF8.GetString

Здесь - это пример вызова участника, но мои попытки создать что-то подобное для моего случая на данный момент провалились.

Ответы [ 2 ]

2 голосов
/ 19 апреля 2019

При условии, что входной объект напечатан правильно, да:

filter Invoke-Method {
  param(
    [System.Management.Automation.PSMethod]
    $Method
  )

  return $Method.Invoke($_)
}

(65..74 -as [byte[]]) |Invoke-Method -Method ([System.Text.Encoding]::UTF8.GetString)
0 голосов
/ 19 апреля 2019

Полезный ответ Матиаса Р. Йессена показывает изящное решение вашего вопроса в ответ на вопрос.

Однако подход ограничен передачей статического метода для передачи объекта конвейера под рукой, тогда как PowerShell имеет встроенную гибкая команда обработки ввода для каждого конвейера : командлет ForEach-Object со встроенным псевдонимом %, которому вы передаете блок скрипта ({ ... }) внутри из которых $_ относится к объекту ввода конвейера под рукой):

PS> , [byte[]] (0x68, 0xc3, 0xaf) | % { [Text.Encoding]::UTF8.GetString($_) }
hï

Обратите внимание, что для преобразования байтового массива, представляющего текст в кодировке UTF8, обратно в строку, вы должны отправить его как целое через конвейер, что является унарным оператором построения массива , достигается здесь (он помещает байтовый массив в вспомогательный массив, который при перечислении в конвейере отправляет байтовый массив целиком).

Синтаксически все становится еще проще, если метод invoke является членом каждого входного объекта конвейера , и в этом случае вы можете использовать оператор операции (PSv3 +):

# Call the .ToUpper() method on each input string:
PS> 'foo', 'bar' | % ToUpper # short for: 'foo', 'bar' | % { $_.ToUpper() }
FOO
BAR

Подробнее см. . .


Особенности производительности :

Написано в PowerShell Core 6.2.0.

Удивительно, но оператор операции - несмотря на то, что блок скрипта не задействован - на медленнее , чем эквивалентный синтаксис блока скрипта ; например, 'foo', 'bar' | % ToUpper медленнее, чем 'foo', 'bar' | % { $_.ToUpper() }

Определение самая быстрая функция фильтра , но, как указано, она ограничена статическими методами (преимущество в скорости превратится в противоположность, если вы передадите операцию для выполнения через блок сценария или по члену имя с использованием отражение с помощью .psobject.Methods).

Однако, , если производительность имеет первостепенное значение и вам нужно вызывать метод для каждого входного объекта, вы можете определить функцию фильтра с помощью жестко запрограммированного вызова метода:

filter ToUpper { $_.ToUpper() }
'foo', 'bar' | ToUpper  # much faster than: 'foo', 'bar' | % ToUpper
...