.net 检查PowerShell中的IEnumerable是否为空
如果.net 检查PowerShell中的IEnumerable是否为空,.net,powershell,ienumerable,.net,Powershell,Ienumerable,如果IEnumerable为空,是否有本机PowerShell测试方法 我知道我可以这样打电话: [Linq.Enumerable]::Any($enumeration) 但我希望有一种更自然的方式。不幸的是,从Windows PowerShell v5.1/PowerShell[Core]v7.0开始,没有PowerShell自然方式。[Linq.Enumerable]::Any()至少是简洁的,但它可以在各种情况下中断: # These invocations all FAIL with
IEnumerable
为空,是否有本机PowerShell测试方法
我知道我可以这样打电话:
[Linq.Enumerable]::Any($enumeration)
但我希望有一种更自然的方式。不幸的是,从Windows PowerShell v5.1/PowerShell[Core]v7.0开始,没有PowerShell自然方式。
[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
(其计算结果为“null集合”)没有实现&{}
([IEnumerable]
或通用对应项),但在PowerShell世界中,一切都是可枚举的,即使是标量和[System.Collections.IEnumerable]
,但后者仅在管道中,而不是使用$null
。值得注意的例外是“null集合”(foreach
),其唯一目的是表示没有什么可枚举的内容(因此,您可以认为,作为一种特殊的枚举情况,它应该实现[System.Management.Automation.Internal.AutomationNull]::Value
)[IEnumerable]
- 但是,
确实实现了1,2,3
:它是一个类型为[IEnumerable]
的常规PowerShell数组;奇怪的是,虽然您可以通过显式的[object[]]
强制转换来修复这种特殊情况,但这显然不是一种通用的解决方案,因为向数组的潜在转换会强制执行完全枚举-有关详细信息,请参阅底部部分[object[]]
- 笨拙且难以记忆
- 要求输入已经存储在变量中(
,在上面的示例中)$enumerable
[object[]]
)
因此,本机PowerShell解决方案将是一个假设的测试任何
cmdlet:
- 通过管道逐个对象接收输入
- 如果至少接收到一个输入对象,则输出
$True
Test Any
cmdlet需要执行此操作才能有效工作(以防止完全枚举):
- 可以找到长期存在的功能请求
- 高效
实现可在我的中找到,由提供;除了依赖私有类型之外,在会话中首次使用时,还将导致按需编译性能损失测试通过使用私有PowerShell类型围绕限制工作的任何
可选阅读:与PowerShell阵列一起使用
[Linq.Enumerable]::Any($Enumerable)
1,2,3
(通常表示为@(1,2,3)
,但这是不必要的)是PowerShell默认数组类型[object[]
数组的实例
我不清楚为什么不能按原样将这些数组传递给.Any()
,因为它确实可以显式转换为相同的类型:[Linq.Enumerable]::Any([object[]](1,2,3))#OK
最后,使用特定类型构造的数组也可以按原样传递:$intArr=[int[](1,2,3);[Linq.Enumerable]::任何($intArr)#正常
如果有人知道为什么您不能在此上下文中使用直接构造的
[object[]]
数组,以及是否有充分的理由,请告诉我们。注释不用于进一步讨论;本次对话密切相关:
# 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 = $enumerable.Where({ $true }, 'First').Count -ne 0