热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

powershell在什么条件下展开管道中的项目?

如何解决《powershell在什么条件下展开管道中的项目?》经验,为你挑选了1个好方法。

考虑以下:

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

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

$l 当它进入管道时被"展开". 这个答案表明powershell展开了所有集合. 哈希表是一个集合.但是,哈希表当然不受管道的影响:

function OutputHashtable{
    $h = @{nested=@{prop1=10;prop2=20}}
    $h
}

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

这条评论表明,所有IEnumerable都转换为对象数组.但是,数组和散列表都是不可数的:

@(,(10,20)) -is [collections.ienumerable]
#True
@{nested=@{prop1=10;prop2=20}} -is [collections.ienumerable]
#True

究竟,PowerShell将对象"展开"到管道中的条件是什么?



1> alx9r..:

实证检验结果

我宁愿对这些结果有一个分析基础,但我需要一个答案,所以我可以继续前进.因此,以下是我在实证测试中的结果,以发现哪些集合由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被调用Out-Collection并位于此github存储库中.


我担心一个坚实的基础,一个答案很可能涉及反编译Powershell,看看它的特殊小脑是如何连接的...但不管怎样,这是一个很好的努力.
现在,PowerShell是开源的,无需交付使用:https://github.com/PowerShell/PowerShell
推荐阅读
author-avatar
大瑞Y
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有