Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 检查PowerShell中的IEnumerable是否为空_.net_Powershell_Ienumerable - Fatal编程技术网

.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]
    [System.Collections.IEnumerable]
    或通用对应项),但在PowerShell世界中,一切都是可枚举的,即使是标量和
    $null
    ,但后者仅在管道中,而不是使用
    foreach
    。值得注意的例外是“null集合”(
    [System.Management.Automation.Internal.AutomationNull]::Value
    ),其唯一目的是表示没有什么可枚举的内容(因此,您可以认为,作为一种特殊的枚举情况,它应该实现
    [IEnumerable]

  • 但是,
    1,2,3
    确实实现了
    [IEnumerable]
    :它是一个类型为
    [object[]]
    的常规PowerShell数组;奇怪的是,虽然您可以通过显式的
    [object[]]
    强制转换来修复这种特殊情况,但这显然不是一种通用的解决方案,因为向数组的潜在转换会强制执行完全枚举-有关详细信息,请参阅底部部分

(PSv4+)是一个健壮但笨重的PowerShell纯本机功能解决方案,可处理上述所有情况:

以上是:

  • 笨拙且难以记忆
  • 要求输入已经存储在变量中(
    $enumerable
    ,在上面的示例中)
但是,在PowerShell的上下文中,延迟求值通常来自对cmdlet的直接调用,cmdlet通过管道逐个对象发送其输出对象(换句话说,执行延迟求值的是PowerShell管道),当您在变量中捕获输出时,该方面将丢失,因为Powershell然后在数组中静态收集输出(
[object[]]

因此,本机PowerShell解决方案将是一个假设的
测试任何
cmdlet

  • 通过管道逐个对象接收输入
  • 如果至少接收到一个输入对象,则输出
    $True
但是,从Windows PowerShell v5.1/PowerShell Core v6.1起,无法按需停止管道,而
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