tl;dr
在 PowerShell 条件/隐式布尔上下文中:
将数组作为 LHS,-eq 等可识别数组的运算符总是也输出数组。
由于您的数组元素都是 $null 并且您与 $null 进行比较,因此您的比较是有效的no-op - 例如,@( $null ) -eq $null 导致 @( $null ) - 并且您的条件相当于:
[bool] @( $null, $null ) # -> $true - array with 2+ elements is always $True
[bool] @( $null ) # -> $false(!) - treated like: [bool] $null
也许令人惊讶的是,隐式布尔逻辑将管道逻辑应用于数组:
也就是说,一个单个元素数组(在概念上)是unwrapped并且它的元素被解释为一个布尔值。
因此,[bool] @( $null ) 被视为与 [bool] $null 相同,即 $false。
通常,@( <one-and-only-element> )(或, <one-and-only-element>)在布尔上下文中被视为与<one-and-only-element> 相同。
相比之下,如果一个数组有2个或更多元素,它总是在布尔上下文中$true,即使所有它的元素将被单独视为$false。
测试任意数组是否为空的解决方法:
基于.Count 属性的条件:
if ( (<array>).Count ) { $true } else { $false }
您可以附加-gt 0,但这并不是绝对必要的,因为任何非零值都隐含为$true。
应用于您的示例:
PS> if ( ( @($null) -eq $null ).Count ) { $true } else { $false }
True
测试任意值是否为(标量)$null:
if ($null -eq <value>) { $true } else { $false }
注意 $null 必须用作 LHS 以防止数组过滤逻辑生效,<value> 应该是一个数组。
这也是为什么带有 PowerShell 扩展的 Visual Studio Code 建议“$null 应该在比较的左侧”,如果您编写类似 $var -eq $null 的内容。
[1] To-Boolean 转换摘要: