Список унаследованных методов PowerShell с помощью Get-Member

Я изучаю, какие функции конвейера также доступны в виде методов. Например... @('1', '2', '3', '2') | where {$_ -in @('2')}вернет две «2». Но я тоже умею ... @('1', '2', '3', '2').Where({$_ -in @('2')}) и получите тот же результат.

Я также хочу Group, а пока @('1', '2', '3', '2') | group {$_.Count -gt 1}не выполняет фактическую группировку, которую я хочу, это делает ... что-то. Но @('1', '2', '3', '2').Group({$_.Count -gt 1}) терпит неудачу с Method invocation failed because [System.String] does not contain a method named 'Group'.

Так что это заставило меня искать то, что доступно как внутренние методы. @('1') | Get-Member -MemberType Method -Force | Format-Table даже не включает Whereи все же Метод существует. Поэтому я предполагаю, что он наследует этот метод. Но я не знаю, как включить унаследованные методы. Я хотя -Force сделал бы это, но это не так, и не делает -View предоставьте более подробную информацию.

Есть ли способ изучить эти внутренние методы, такие как .Where()? И, возможно, косвенно, есть ли способ группировки как метода, а не конвейера?

2 ответа

Решение

Ответ Дабомбера полезен , но позвольте мне попытаться дать систематический обзор:

Методы массива и являются экземплярами так называемых внутренних членов ; в PowerShell 7.1 не существует других таких встроенных методов обработки массивов (обработки коллекций).

Внутренние члены являются члены (свойства и методы) , что двигатель PowerShell выставляет на объектах любого типа - за исключением , если объект имеет нативную элемент типа .NET с тем же именем, которое имеет приоритет.

Ограничения обнаружения, начиная с PowerShell 7.1 / конец 2020 г .:

  • Внутренние члены не могут быть обнаружены через Get-Member

  • Завершение табуляции работает только для и (для значений коллекции), но не для других внутренних членов, таких как свойство (см. Ниже).

  • В концептуальном справки разделеabout_Intrinsic_Members обсуждаются внутренние члены, но - на момент написания этой статьи - не полностью .

Вкратце: на момент написания этой статьи вы не могли обнаруживать внутренние члены программно .


Список внутренних членов :

  • Внутренние члены, обеспечивающие унифицированную обработку коллекций (массивов) и скаляров :

    • PowerShell добавляет свойства (псевдонимы друг друга) даже к скалярам (при условии, что у них нет свойств с одинаковым именем, присущих типу), с разумным сообщением ненулевого скаляра (например, (42).Count) и отчетности 0 ( $null.Count)

      • Подводные камни :
        • Доступ к этим свойствам во время Set-StrictMode -Version 2или выше, неожиданно вызывает ошибки завершения оператора, потому что механизм обрабатывает их как несуществующие; эта давняя ошибка обсуждается в выпуске GitHub №2798 .

        • IEnumerableэкземпляры, такие как возвращаемые методами LINQ, не являются коллекциями сами по себе, и их вызов запускает перечисление и вместо этого возвращает значение свойства из каждого перечисляемого элемента (по умолчанию 1); например, [Linq.Enumerable]::Range(1,3).Count возвращает массив 1, 1, 1 вместо 3.

        • Существует ошибка в Windows PowerShell (как последней и окончательной версии, 5.1), которая впоследствии была исправлена в PowerShell (ядро): экземпляры неожиданно у не имеют .Count а также .Lengthproperties ( исходный отчет об ошибке см. в выпуске GitHub № 3671 ) - см. этот ответ .

    • Точно так же PowerShell позволяет вам индексировать даже в скаляр (опять же, если только он не вытеснен собственным индексатором типа, таким как индексатор XmlElement); например, (42)[0] а также (42)[-1] оба возвращаются 42, т.е. сам скаляр.

  • Внутренние элементы обработки коллекции :

    • Это (только) .Where()и методы, описанные выше.

    • Обратите внимание, что в интересах единой обработки коллекций и скаляров эти методы также работают со скалярами ; например, (42).ForEach({ $_ + 1 }) дает 43.

    • Подводные камни :

      • В Windows PowerShell (с момента исправления в PowerShell [Core] 7+) некоторые типы скаляров, в частности [pscustomobject]и - не предоставлять эти методы, что следует рассматривать как ошибку .

      • В System.Collections.Generic.List<T> тип коллекции имеет свой .ForEach()метод, который, следовательно, затеняет PowerShell; этот типизированный метод не поддерживает использование $_ ни производства продукции.

  • Внутренние члены для размышлений (недоступно на $null):

    • В .psobjectсвойство - это богатый источник размышлений о любом объекте, например, о его списке свойств; например, (Get-Date).psobject.Properties перечисляет метаданные обо всех публичных свойствах экземпляров System.DateTime.

    • .pstypenames (также доступно как .psobject.TypeNames) перечисляет все имена типов ETS (система расширенных типов), связанные с экземпляром; по умолчанию свойство содержит полные имена типа .NET объекта и его базового типа (ов).

    • В .psbase, .psextended, а также psadaptedсвойства возвращают категоризированные подмножества членов типа, а именно элементы .NET-native, ETS-added и адаптированные элементы.

      • Адаптированные члены - это члены, отображающие информацию из другого представления данных, как если бы они были членами собственного типа, особенно в контексте CIM (WMI) и адаптации PowerShell к XML DOM.

      • Например, [xml] ( System.Xml.XmlDocument) экземпляры имеют участников во всех трех категориях; пытаться $xml = ([xml] '<someElement>some text</someElement>'); '-- .psbase:'; $xml.psbase; '-- .psextended'; $xml.psextended; '-- .psadapted'; $xml.psadapted

Ваши массивы разворачиваются по конвейеру, поэтому @('1') | Get-Member -MemberType Method -Force показывает элементы для строки.

Вы можете обойти это, отправив его как второй объект массива

      ,@('1') | Get-Member -MemberType Method

вывод без перечисления

      Write-Output -NoEnumerate @('1') | Get-Member -MemberType Method

или передать его как параметр, а не через конвейер.

      Get-Member -InputObject @('1') -MemberType Method

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

Существует список методов массивов здесь , хотя я понятия не имею , почему не все из них появляются, возможно , это намеренное частью Get-Member командлет или, может быть, они являются частью самого языка PowerShell, а не собственными методами.

Другие вопросы по тегам