问题
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.psobjectproperty (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
.Countand.Lengthproperties (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 reporting1(e.g.,(42).Count), and$nullreporting0($null.Count)- Pitfalls:
Accessing these properties while
Set-StrictMode -Version 2or 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
.Counton them triggers enumeration and returns a.Countproperty value from each enumerated element instead (which defaults to1); e.g.,[Linq.Enumerable]::Range(1,3).Countreturns array1, 1, 1instead of3.
- Pitfalls:
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 return42, 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 })yields43.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
.psobjectproperty is a rich source of reflection on any object, such as its list of properties; e.g.,(Get-Date).psobject.Propertieslists 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, andpsadaptedproperties 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