【问题标题】:PowerShell Array list assignment and Where-Object fails when Where-Object returns one item. Works with 2+ items当 Where-Object 返回一项时,PowerShell 数组列表分配和 Where-Object 失败。适用于 2 个以上的项目
【发布时间】:2023-01-18 04:12:50
【问题描述】:

长期搜索者,第一次张贴者。 :-)

将数组列表传递给 Where-Object 并将其分配回另一个数组列表时,如果 Where-Object 的结果是单个项目,则会生成转换错误。但是当返回两个或多个项目时,相同的命令会成功。这是 PowerShell 错误还是我遗漏了什么?

为什么会失败?

PS C:\> [System.Collections.ArrayList]$AL1 = @(1,2,3)
PS C:\> [System.Collections.ArrayList]$AL2 = $AL1 | Where-Object {$_ -ge 3}
Cannot convert the "3" value of type "System.Int32" to type "System.Collections.ArrayList".
At line:1 char:1
+ [System.Collections.ArrayList]$AL2 = $AL1 | Where-Object {$_ -ge 3}
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : MetadataError: (:) [], ArgumentTransformationMetadataException
    + FullyQualifiedErrorId : RuntimeException

但如果 Where-Object 的结果是两个或更多项,它不会失败。

PS C:\> [System.Collections.ArrayList]$AL1 = @(1,2,3)
PS C:\> [System.Collections.ArrayList]$AL2 = $AL1 | Where-Object {$_ -ge 2}
PS C:\> $AL2
2
3
PS C:\>

如果您首先通过 New-Object 创建第二个数组列表,则赋值也会成功。

PS C:\> $AL3 = New-Object System.Collections.ArrayList
PS C:\> $AL3 = $AL1 | Where-Object {$_ -ge 3}
PS C:\> $AL3
3

在 PSVersion 5.1.19041.1682 和核心 7.0.7 上测试

【问题讨论】:

    标签: powershell powershell-core


    【解决方案1】:

    是的,这是预期的,PowerShell 枚举所有输出,并且由于表达式产生了一项:

    $AL1 | Where-Object { $_ -ge 3 }
    

    它试图将 int 强制转换为 System.Collections.ArrayList 类型,但是只有实现 IEnumerable 的类型才能被强制转换为它,因此出现错误:

    PS > [System.Collections.ArrayList] 3
    

    InvalidArgument:无法将类型“System.Int32”的值“3”转换为类型“System.Collections.ArrayList”。

    您有两个简单的解决方法:

    1. 不要将您的变量限制为System.Collections.ArrayList 类型,让 PowerShell 动态分配结果类型。
    2. 用 Array subexpression operator @( ) 包裹您的表达式,因此,无论表达式产生多少元素,类型永远是IEnumerable:
      [System.Collections.ArrayList] $AL1 = @(1, 2, 3)
      $AL2 = @($AL1 | Where-Object { $_ -ge 3 })
      

      使用Write-Output -NoEnumerate 或Comma operator , 也可以使用其他解决方法:

      [System.Collections.ArrayList] $AL1 = @(1, 2, 3)
      $AL2 = $AL1 | Where-Object { $_ -ge 3 } | Write-Output -NoEnumerate
      $AL2 = , ($AL1 | Where-Object { $_ -ge 3 })
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-10-07
      • 1970-01-01
      • 2011-05-27
      • 2014-06-15
      • 2018-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多