PowerShell list inherited methods with Get-Member

寵の児 提交于 2021-01-04 04:20:46

问题


I am exploring what pipeline functionality is also available as methods. For example... @('1', '2', '3', '2') | where {$_ -in @('2')} will return the two '2'. But I can also do... @('1', '2', '3', '2').Where({$_ -in @('2')}) and get the same result.

I also want to Group, and while @('1', '2', '3', '2') | group {$_.Count -gt 1} doesn't do the actual grouping I want, it does... something. But @('1', '2', '3', '2').Group({$_.Count -gt 1}) fails with Method invocation failed because [System.String] does not contain a method named 'Group'.

So that got me looking for what IS available as intrinsic methods. @('1') | Get-Member -MemberType Method -Force | Format-Table doesn't even include Where and yet the Method is there. So I assume it is inheriting that method. But I don't know how to include inherited Methods. I though -Force would do it but it doesn't, nor does -View provide any more detail.

Is there a way to explore these intrinsic methods such as .Where()? And perhaps tangentially, is there a way to Group as a method rather than with the pipeline?


回答1:


Dabombber's answer is helpful, but let me try to give a systematic overview:

The .Where() and .ForEach() array methods are instances of what is semi-officially known as intrinsic members; no other such intrinsic array-processing (collection-processing) methods exist as of PowerShell 7.1

Intrinsic members are members (properties and methods) that the PowerShell engine exposes on objects of any type - except if the object has a native .NET type member of the same name, which takes precedence.

Discovery limitations, as of PowerShell 7.1 / late 2020:

  • Intrinsic members cannot be discovered via Get-Member

    • GitHub proposal #11798 aims to introduce this ability.
  • Tab completion works only for .Where() and .ForEach() (on collection values), but not for other intrinsic members, such as the .psobject property (see below).

  • There is no conceptual help topic that discusses intrinsic members.

    • GitHub docs issue #5627 suggests introducing one.

In short: as of this writing, you cannot discover intrinsic members programmatically.


List of intrinsic members:

  • Intrinsic members that enable unified treatment of collections (arrays) and scalars:

    • PowerShell adds .Count and .Length properties (aliases of each other) even to scalars (assuming they don't have type-native properties of the same name), with an non-null scalar sensibly reporting 1 (e.g., (42).Count), and $null reporting 0 ($null.Count)

      • Pitfalls:
        • Accessing these properties while Set-StrictMode -Version 2 or higher is in effect unexpectedly causes statement-terminating errors, because the engine treats them as non-existent; this long-standing bug is discussed in GitHub issue #2798.

        • IEnumerable instances such as returned by LINQ methods aren't collections per se, and calling .Count on them triggers enumeration and returns a .Count property value from each enumerated element instead (which defaults to 1); e.g., [Linq.Enumerable]::Range(1,3).Count returns array 1, 1, 1 instead of 3.

    • Similarly, PowerShell allows you to index even into a scalar (again, unless preempted by a type-native indexer, such as that of XmlElement); e.g., (42)[0] and (42)[-1] both return 42, i.e. the scalar itself.

  • Collection-processing intrinsic members:

    • These are (only) the .Where() and .ForEach() methods discussed above.

    • Note that, in the the interest of unified treatment of collections and scalars, these methods also work on scalars; e.g., (42).ForEach({ $_ + 1 }) yields 43.

    • Pitfalls:

      • In Windows PowerShell (since fixed in PowerShell [Core] 7+), some types of scalars - notably [pscustomobject] and [xml] - do not provide these methods, which should be considered a bug.

      • The System.Collections.Generic.List<T> collection type has its own .ForEach() method that therefore shadows PowerShell's; this type-native method neither supports the use of $_ nor producing output.

  • Intrinsic members for reflection (not available on $null):

    • The .psobject property is a rich source of reflection on any object, such as its list of properties; e.g., (Get-Date).psobject.Properties lists metadata about all public properties of instances of System.DateTime.

    • .pstypenames (also available as .psobject.TypeNames) lists all ETS (Extended Type System) type names associated with an instance; by default, the property contains the full names of the object's .NET type and its base type(s).

    • The .psbase, .psextended, and psadapted properties return categorized subsets of type members, namely .NET-native, ETS-added, and adapted members.

      • Adapted members are members that surface information from a different data representation as if they were native type members, notably in the context of CIM (WMI) and PowerShell's adaptation of the XML DOM.

      • For instance, [xml] (System.Xml.XmlDocument) instances have members in all three categories; try $xml = ([xml] '<someElement>some text</someElement>'); '-- .psbase:'; $xml.psbase; '-- .psextended'; $xml.psextended; '-- .psadapted'; $xml.psadapted




回答2:


Your arrays are getting unrolled through the pipeline, so @('1') | Get-Member -MemberType Method -Force is showing members for a string.

You can bypass that by sending it as the second object of an array

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

outputting it without enumeration

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

or passing it as a parameter instead of through the pipeline.

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

Some of the methods may also be static, so you could use the -Static switch for Get-Member.

There is a list of array methods here, although I have no idea why not all of them show up, perhaps it's an intentional part of the Get-Member cmdlet or maybe they're part of the PowerShell language itself rather than proper methods.



来源:https://stackoverflow.com/questions/65454593/powershell-list-inherited-methods-with-get-member

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!