如果IEnumerable
为空,是否有原生PowerShell方法进行测试?
我知道我可以这样打电话给Linq.Enumerable.Any
:
[Linq.Enumerable]::Any($enumeration)
但我希望有一种更本土化的方式。
答案 0 :(得分:1)
不幸的是,从Windows PowerShell v5.1 / PowerShell Core v6.1 开始,没有 PowerShell-native方式,而[Linq.Enumerable]::Any()
至少是# These invocations all FAIL with
# 'Cannot find an overload for "Any" and the argument count: "1"'
foreach ($enumerable in 1.5, $null, (& {}), (1,2,3)) {[Linq.Enumerable]::Any($enumerable)}
简洁,它可以在各种场景中打破:
1.5
现在,$null
,& {}
和[IEnumerable]
(评估为" null集合")执行而非实施[System.Collections.IEnumerable]
(foreach
或通用副本),但在PowerShell 的世界中,所有都是可枚举的,甚至标量,并且在中管道 - 但不是$null
(!) - 偶然[System.Management.Automation.Internal.AutomationNull]::Value
。值得注意的例外是" null集合" ([IEnumerable]
),其唯一目的是表明没有没有进行枚举(因此你可以认为,作为一个特殊的枚举案例,应该< / em>实施1, 2, 3
)。
但是,[IEnumerable]
实现[object[]]
:它是[object[]]
类型的常规PowerShell数组;虽然你可以通过 - 一个明确的# Returns $True if $enumerable results in enumeration of at least 1 element.
# Note that $null is NOT considered enumerable in this case, unlike
# when you use `$null | ...`
$haveAny = try { $enumerable.ForEach({ Throw }); $False } catch { $True }
强制转换来解决这个特殊情况,但它显然不是一般解决方案,因为可能转换为数组强制完全枚举 - 请参阅底部更多信息。
一个强大但又繁琐的PowerShell原生功能解决方案可以处理上述所有情况(PSv4 +):
$enumerable
以上是:
[object[]]
)中。但是,在PowerShell延迟评估的上下文中,通常来自直接调用 cmdlet 通过管道通过管道发送其输出对象 (换句话说,执行延迟评估的是PowerShell 管道),当您在中捕获输出时,该方面丢失变量,因为Powershell然后在数组(Test-Any
)中静态收集输出。
因此,原生PowerShell解决方案将 假设的 $True
cmdlet :
Test-Any
。从Windows PowerShell v5.1 / PowerShell Core v6.1开始,无法停止按需管道,Test-Any
cmdlet需要执行此操作为了有效地工作(为了防止完全枚举):
可以找到长期功能请求on GitHub。
可以在this answer中找到高效[Linq.Enumerable]::Any($enumerable)
实施,该实施通过使用私有 PowerShell类型来解决限制问题。我的,PetSerAl的礼貌;除了依赖私有类型之外,您还会在会话中首次使用时产生按需编译性能损失。
可选阅读:1, 2, 3
与PowerShell数组一起使用
@(1, 2, 3)
(通常表示为[object[]]
,但这是不必要的)是.Any()
数组的实例,PowerShell的默认数组类型。
我不清楚为什么你不能将这些数组传递给[Linq.Enumerable]::Any([object[]] (1,2,3)) # OK
as-is ,因为它确实可以使用显式转换为相同类型:[object[]]
收集命令的多对象输出也(隐式)创建一个[Linq.Enumerable]::Any((Get-ChildItem)) # OK
数组,然而可以传递-is:$intArr = [int[]] (1, 2, 3); [Linq.Enumerable]::Any($intArr) # OK
最后,使用特定类型构造的数组也可以按原样传递:
[object[]]
如果有人知道为什么你不能在这种情况下使用直接构造的int
数组,以及是否有充分的理由,请告诉我们。