gpt4 book ai didi

powershell - powershell 在什么情况下会在管道中展开项目?

转载 作者:行者123 更新时间:2023-12-03 23:50:53 25 4
gpt4 key购买 nike

考虑以下:

function OutputArray{
$l = @(,(10,20))
$l
}

(OutputArray) -is [collections.ienumerable]
# C:\ PS> True
(OutputArray).Count
# C:\ PS> 2
$l is "unrolled" when it enters the pipeline . This answer states that powershell unrolls all collections . A hashtable is a collection .但是,哈希表当然不受管道的影响:
function OutputHashtable{
$h = @{nested=@{prop1=10;prop2=20}}
$h
}

(OutputHashtable) -is [collections.ienumerable]
# C:\ PS> True
(OutputHashtable).Count
# C:\ PS> 1

This comment suggests that it is all IEnumerable that are converted to object arrays .但是,数组和哈希表都是可枚举的:
@(,(10,20)) -is [collections.ienumerable]
#True
@{nested=@{prop1=10;prop2=20}} -is [collections.ienumerable]
#True

Powershell 将对象“展开”到管道中的确切条件是什么?

最佳答案

实证检验结果
我宁愿对这些结果有一个分析基础,但我需要一个答案,这样我才能继续前进。因此,以下是我进行实证测试的结果,以发现哪些集合被 powershell 的管道展开,哪些不是:
列中的 True 表示可能发生了一些展开。

StartingType                          ChangedInCmdlet^  ChangedWhenEmitted**
------------ --------------- ------------------
System.String
System.Collections.ArrayList True True
System.Collections.BitArray True True
System.Collections.Hashtable
System.Collections.Queue True True
System.Collections.SortedList
System.Collections.Stack True True
System.Collections.Generic.Dictionary
System.Collections.Generic.List True True
这些是一行 powershell 的结果,如下所示:
$result = $starting | Cmdlet
^ ChangedInCmdlet列表示 $starting的类型当它出现在 Cmdlet 里面时是不同的.
** ChangedWhenEmitted列表示 $result的类型分配给 $result 时与在 Cmdlet 中发出时不同.
对于某些类型,可能存在一些细微差别。可以通过查看下面测试脚本输出的详细信息来分析这种细微差别。整个测试脚本如下。
测试脚本
[System.Reflection.Assembly]::LoadWithPartialName('System.Collections') | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName('System.Collections.Generic') | Out-Null

Function BackThroughPipeline{
[CmdletBinding()]
param([parameter(position=1)]$InputObject)
process{$InputObject}
}

Function EmitTypeName{
[CmdletBinding()]
param([parameter(ValueFromPipeline=$true)]$InputObject)
process{$InputObject.GetType().FullName}
}

$objects = (New-Object string 'TenTwentyThirty'),
([System.Collections.ArrayList]@(10,20,30)),
(New-Object System.Collections.BitArray 16),
([System.Collections.Hashtable]@{ten=10;twenty=20;thirty=30}),
([System.Collections.Queue]@(10,20,30)),
([System.Collections.SortedList]@{ten=10;twenty=20;thirty=30}),
([System.Collections.Stack]@(10,20,30)),
(& {
$d = New-Object "System.Collections.Generic.Dictionary``2[System.String,int32]"
('ten',10),('twenty',20),('thirty',30) | % {$d.Add($_[0],$_[1])}
$d
}),
(& {
$l = New-Object "System.Collections.Generic.List``1[int32]"
10,20,30 | % {$l.Add($_)}
$l
})

$objects |
% {
New-Object PSObject -Property @{
StartingType = $_.GetType().FullName
StartingCount = $_.Count
StartingItems = $_
InCmdletType = $_ | EmitTypeName
InCmdletCount = ($_ | EmitTypeName).Count
AfterCmdletType = (BackThroughPipeline $_).GetType().FullName
AfterCmdletItems = (BackThroughPipeline $_)
AfterCmdletCount = (BackThroughPipeline $_).Count
ChangedInCmdlet = if ($_.GetType().FullName -ne ($_ | EmitTypeName) ) {$true};
ChangedWhenEmitted = if (($_ | EmitTypeName) -ne (BackThroughPipeline $_).GetType().Fullname ) {$true}
}
}
Out-Collection Cmdlet
这个测试最终让我创建了一个 cmdlet,它有条件地将集合包装在牺牲数组中,以(希望)可靠地防止循环展开。该 cmdlet 名为 Out-Collection并且在 this github repository .

关于powershell - powershell 在什么情况下会在管道中展开项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28702588/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com