简体   繁体   English

PowerShell 当 Where-Object 返回一项时,数组列表分配和 Where-Object 失败。 适用于 2 个以上的项目

[英]PowerShell Array list assignment and Where-Object fails when Where-Object returns one item. Works with 2+ items

Long time searcher, first time poster.长期搜索者,第一次张贴者。 :-) :-)

When piping an array list to Where-Object and assigning it back to another array list, a conversion error is generated when the result of the Where-Object is a single item.将数组列表传递给 Where-Object 并将其分配回另一个数组列表时,如果 Where-Object 的结果是单个项目,则会生成转换错误。 But the same command succeeds when two or more items are returned.但是当返回两个或多个项目时,相同的命令会成功。 Is this a PowerShell bug or am I missing something?这是 PowerShell 错误还是我遗漏了什么?

Why does this fail?为什么会失败?

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

But if the result of the Where-Object is two or more items it does not fail.但如果 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:\>

Also the assignment succeeds if you first create the second array list via New-Object.如果您首先通过 New-Object 创建第二个数组列表,则赋值也会成功。

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

Tested on PSVersion 5.1.19041.1682 and core 7.0.7在 PSVersion 5.1.19041.1682 和核心 7.0.7 上测试

Yes this is expected, PowerShell enumerates all output and, since one item results from the expression:是的,这是预期的,PowerShell 枚举了所有 output 并且,因为表达式产生了一个项目:

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

Its trying to coerce an int to the type System.Collections.ArrayList , however only types implementing IEnumerable can be coerced to it, hence the error:它试图将int强制转换为System.Collections.ArrayList类型,但是只能将实现IEnumerable的类型强制转换为它,因此出现错误:

PS \> [System.Collections.ArrayList] 3

InvalidArgument: Cannot convert the "3" value of type "System.Int32" to type "System.Collections.ArrayList". InvalidArgument:无法将类型“System.Int32”的值“3”转换为类型“System.Collections.ArrayList”。

You have three easy workarounds:您有三个简单的解决方法:

  1. Don't constrain your variable to be of the type System.Collections.ArrayList , let PowerShell dynamically assign the resulting type.不要将变量限制为System.Collections.ArrayList类型,让 PowerShell 动态分配结果类型。
  2. Wrap your expression with the Array subexpression operator @( ) , so, no matter how many elements results from the expression, the type will always be an IEnumerable :使用Array 子表达式运算符@( )包装您的表达式,因此,无论表达式产生多少元素,类型始终为IEnumerable
[System.Collections.ArrayList] $AL1 = @(1, 2, 3)
[System.Collections.ArrayList] $AL2 = @($AL1 | Where-Object { $_ -ge 3 })
  1. Use the .Where method instead which always returns Collection`1 (an IEnumerable ):使用.Where方法,它总是返回Collection`1 (一个IEnumerable ):
[System.Collections.ArrayList] $AL1 = @(1, 2, 3)
[System.Collections.ArrayList] $AL2 = $AL1.Where{ $_ -ge 3 }

Other workarounds are possible either using Write-Output -NoEnumerate or Comma operator , :使用Write-Output -NoEnumerateComma operator ,也可以使用其他解决方法:

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

As for:至于:

Also the assignment succeeds if you first create the second array list via New-Object .如果您首先通过New-Object创建第二个数组列表,则分配也会成功。

Correct, you're not constraining the variable in this case:正确,在这种情况下您没有约束变量:

$AL3 = New-Object System.Collections.ArrayList
$AL3 = $AL1 | Where-Object { $_ -ge 3 }
$AL3.GetType() # => Int32, no longer an ArrayList

For more info, see relevant documentation: about Variables .有关详细信息,请参阅相关文档: 关于变量

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM