1

我发现当我编写以下函数时:

function test {
    Write-Host ($input | Measure-Object).Count
    Write-Host ($input | Measure-Object).Count
}

带样本输入:

dir | test

它在控制台上写道:

18
0

我认为这是因为 Measure-Object 的第一个管道覆盖了 $input。我知道一种解决方法,我可以创建一个新数组并传递它:

function test {
    $inp = @($input)
    Write-Host ($inp | Measure-Object).Count
    Write-Host ($inp | Measure-Object).Count
}

但是我不喜欢它,因为我正在引入一个新变量。有没有办法在不影响 $input 的情况下通过管道连接到 cmdlet?

4

2 回答 2

2

尝试这个:

function test {    
 Write-Host ($input | Measure-Object).Count
 $input.reset()
 Write-Host ($input | Measure-Object).Count
}

阅读$input枚举器

于 2012-10-30T14:38:07.477 回答
2

$input是一个ArrayListEnumeratorSimple

C:\Users\roger> $input.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
False    True     ArrayListEnumeratorSimple                System.Object

...这意味着它是一系列项目的枚举器。因此,当您消费其中的物品时,您会用完它们。

我尝试了以下操作:

function foo
{
    $input | select -first 3 | % { Write-Host -ForegroundColor 'Red' $_ }
    $input | % { Write-Host -ForegroundColor 'White' $_ }
}

...表明它select -first 3吃掉了前 3 件东西,但它似乎吞下了所有的东西。

尝试以下操作:

function bar
{
    $n = 0
    foreach ($x in $input) {
        if ( ++$n -eq 3 ) { break }
        Write-Host -ForegroundColor 'Red' $x
    }

    $input | % { Write-Host -ForegroundColor 'White' $_ }
}

dir | bar

...显示差异。

然而,由于 $input 是一个枚举器(严格来说是一个IEnumerator),你可以调用Reset()它来回退它。

请注意,在 .NET-land 中,并非所有枚举数都可以重置。我不确定 PowerShell 中是否有任何情况是$input.

于 2012-10-30T14:38:19.430 回答