我一直在研究一些PowerShell函数来管理我们创建的程序集中实现的对象。我一直在使用的类之一实现了IEnumerable。不幸的是,这导致PowerShell在每个机会展开对象。 (我无法改变该类实现IEnumerable的事实。)
我通过创建PSObject并将自定义对象的属性复制到PSObject,然后返回而不是自定义对象来解决这个问题。但我真的宁愿返回我们的自定义对象。
是否有某种方法,可能是使用我的types.ps1xml文件,从PowerShell隐藏此类的GetEnumerator()方法(或以其他方式告诉PowerShell永远不会展开它)。
答案 0 :(得分:8)
包裹PSObject
可能是最好的方式。
你也可以将它显式地包装在另一个集合中 - PowerShell只打开一个级别。
当您在调用WriteObject
时在C#/ VB / ...中编写cmdlet时,请使用带有第二个参数的重载:如果为false,则PowerShell将不会枚举作为第一个参数传递的对象。
答案 1 :(得分:5)
检查写入输出替换http://poshcode.org/2300,它具有-AsCollection参数,可以避免展开。但基本上,如果您正在编写一个输出集合的函数,并且您不希望该集合展开,则需要使用CmdletBinding和PSCmdlet:
function Get-Array {
[CmdletBinding()]
Param([Switch]$AsCollection)
[String[]]$data = "one","two","three","four"
if($AsCollection) {
$PSCmdlet.WriteObject($data,$false)
} else {
Write-Output $data
}
}
如果你用-AsCollection调用它,你会得到非常不同的结果,虽然他们会在控制台中看到相同的结果。
C:\PS> Get-Array
one
two
three
four
C:\PS> Get-Array -AsCollection
one
two
three
four
C:\PS> Get-Array -AsCollection| % { $_.GetType() }
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String[] System.Array
C:\PS> Get-Array | % { $_.GetType() }
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
True True String System.Object
True True String System.Object
True True String System.Object
答案 2 :(得分:0)
这可能无法直接回答原始问题,因为从技术上讲它不会返回自定义对象本身,但是在尝试显示实现IEnumerable
的自定义类型的属性时,我遇到了类似的问题认为值得分享。将此对象放入Get-Member
和Select-Object
之类的cmdlet中,始终会枚举集合的内容。但是,直接使用这些cmdlet并将对象传递给-InputObject
参数会产生预期的结果。在这里,我以ArrayList
为例,但是$list
可以是您的自定义集合类型的实例:
# Get a reference to a collection instance
$list = [System.Collections.ArrayList]@(1,2,3)
# Display the properties of the collection (in this case, the ArrayList),
# not the items it contains (Int32)
Select-Object -InputObject $list -Property *
# List the members of the ArrayList class, not the contained items
Get-Member -InputObject $list
正如其他评论所提到的,您可以将Select-Object
的结果另存为变量,创建一个新的PSObject
,您可以直接使用它而无需枚举内容:
# Wrap the collection in a PSObject
$obj = Select-Object -InputObject $list -Property *
# Properties are displayed without enumerating contents
$obj
$obj | Format-List
$obj | Format-Table