gpt4 book ai didi

PowerShell Where对象与Where方法

转载 作者:行者123 更新时间:2023-12-03 14:16:38 25 4
gpt4 key购买 nike

我注意到编写PowerShell类行有趣而又奇怪的事情:

class A {

[object] WhereObject(){
return @(1,2) | Where-Object {$_ -gt 2}
}

[object] Where(){
return @(1,2).Where( {$_ -gt 2})
}
}

$a = new-object A
$a.WhereObject() # Throw exception Index was out of range. Must be non-negative and less than the size of the collection.

$a.Where() # Works well

看起来是设计使然。为什么这样工作?

解决方法

将“空”值显式转换为$ null的函数:
function Get-NullIfEmpty {
param(
[Parameter(ValueFromPipeline=$true)][array] $CollectionOrEmtpy
)

begin { $output = $null }

process
{
if($output -eq $null -and $CollectionOrEmtpy -ne $null){
$output = @()
}
foreach ($element in $CollectionOrEmtpy)
{
$output += $element
}
}

end { return $output }
}

在这种情况下,该方法将如下所示:
[object] WhereObject() {
return @(1,2) | Where-Object {$_ -gt 2} | Get-NullIfEmpty
}

我试图从类方法中返回一个空数组,但这也很棘手,因为对于常规函数而言,空数组也意味着“什么也没有”。如果您有像method1-> function-> method2-method1这样的调用链,则抛出相同的异常。因为该函数将空数组转换为空。

因此,在我的情况下,转换为$ null是最佳选择:)

最佳答案

  • (PowerShell v4 +) .Where()方法(在表达式模式下评估),始终返回[System.Collections.ObjectModel.Collection[psobject]]实例:
  • 如果没有输入对象匹配,则该实例只是空的(它没有元素,并且其.Count属性返回0)。

  • 相反, Where-Object cmdlet 使用管道语义,这意味着以下输出行为:
  • 如果未输出任何内容(如果没有与过滤脚本块匹配的内容),则返回值为“空集合”,从技术上讲,它是[System.Management.Automation.Internal.AutomationNull]::Value单例。
  • 如果单个项目匹配,则该项目将按原样输出。
  • 如果多个项目匹配,并且将它们收集在变量中/作为表达式的一部分进行评估,则将它们收集在[object[]]数组中。


  • 至于特定症状-此后 Bruce Payette's answer已经确认是错误。
  • 更新:至少从v7 起,此错误已被修复;返回“nothing”(AutomationNull)现在被强制为$null;看到原始的bug report on GitHub

  • 内部[List[object]]实例用于收集通过内部管道执行的方法调用的输出。如果该内部管道输出“无”(即[System.Management.Automation.Internal.AutomationNull]::Value),则不会将任何对象添加到列表中。但是,后续代码假定列表中至少有一个对象,并且盲目访问索引0,从而导致手头的错误。
    问题的更简单重现:
    class A {
    # Try to return [System.Management.Automation.Internal.AutomationNull]::Value
    # (which is what `& {}` produces).
    [object] WhereObject(){ return & {} }
    }

    $a = new-object A

    $a.WhereObject() # Throw exception Index was out of range. Must be non-negative and less than the size of the collection.
    至于所需的行为:
    如果该方法的代码返回“空集合”,即using C#'s default-value feature,请参见this comment,此修补程序似乎将导致$null获取输出。

    关于PowerShell Where对象与Where方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50956909/

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