当空数组评估为 False 时,为什么空的 Powershell 哈希表评估为 True?

Sim*_*wsi 5 powershell powershell-4.0

我正在 Powershell 4.0 中试验 True 和 False。以下是查看空数组和空哈希表时的结果:

PS C:\Users\simon> $a = @()    
PS C:\Users\simon> if ($a) { Write-Host "True" } else { Write-Host "False" }
False

PS C:\Users\simon> $a = @{}    
PS C:\Users\simon> if ($a) { Write-Host "True" } else { Write-Host "False" }
True
Run Code Online (Sandbox Code Playgroud)

当空数组评估为 False 时,为什么空哈希表评估为 True?

根据 Powershell 文档关于比较运算符

当输入是一组值时,比较运算符返回任何匹配的值。如果集合中没有匹配项,则比较运算符不会返回任何内容。

因此,我希望哈希表和数组在为空时都具有相同的行为,因为它们都是集合。我希望两者都评估为 False ,因为它们不返回任何内容if

gms*_*man 3

这不是一个对/错的问题。您可以使用布尔运算符$true和来测试这一点$false。我用作$h空哈希表@{}

PS C:\> $a = @()
PS C:\> $h = @{}
PS C:\> if ($a -eq $true) { Write-Host "True" } else { Write-Host "False" }
False

if ($h -eq $true)    >  False
if ($a -eq $false)   >  False
if ($h -eq $false)   >  False
Run Code Online (Sandbox Code Playgroud)

也不等于自动变量$null

if($a -eq $null)     >  False
if($h -eq $null)     >  False
Run Code Online (Sandbox Code Playgroud)

根据iRon 的链接Count这是一个更好的测试来查看哈希表/数组是否为空。有关的Length

不同的行为将与基本类型相关。

PS C:\> $a.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

PS C:\> $h.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Hashtable                                System.Object
Run Code Online (Sandbox Code Playgroud)

if这与语句的工作方式和Length属性AFAICS有关。以下是我对多个 StackOverflow 帖子和外部链接的理解(诚然是不稳定的)。


Get-Member行为不同 - 请参阅马蒂亚斯的解释

$a | Get-Member            # Error - Get-Member : You must specify an object for the Get-Member cmdlet.
$h | Get-Member            # TypeName: System.Collections.Hashtable. Has Count method, no Length property
Get-Member -InputObject $a # TypeName: System.Object[]. Has Count method, has Length property
Run Code Online (Sandbox Code Playgroud)

变量的性质Length不同。但哈希表没有属性Length-请参阅 mjolinar 的回答

$a.Length   > 0
$h.length   > 1
Run Code Online (Sandbox Code Playgroud)

结合Ansgar 的链接解释了声明中的不同行为if,因为它似乎隐式获取了Lengthproperty 。它还允许我们这样做:

if ($a.Length -eq $true)    >  False
if ($h.Length -eq $true)    >  True
Run Code Online (Sandbox Code Playgroud)

与 相比,使用[String] .Net 类的IsNullOrEmpty 方法$null会给出不同的输出,我认为因为这也依赖于Length.

if ([string]::IsNullOrEmpty($a))    > True
if ([string]::IsNullOrEmpty($h))    > False
Run Code Online (Sandbox Code Playgroud)