当空数组的计算结果为False时,为什么空的Powershell哈希表计算结果为True?

时间:2017-11-06 02:05:52

标签: powershell powershell-v4.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

为什么当空数组计算为False时,空哈希表的计算结果为True?

根据Powershell文档About Comparison Operators

  

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

从那时起,我希望散列表和数组在它们为空时表现相同,因为它们都是集合。我希望两者都评估为False,因为它们没有返回if子句。

1 个答案:

答案 0 :(得分:1)

这不是真/假的问题。您可以使用布尔运算符$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

也不等于自动变量$null

if($a -eq $null)     >  False
if($h -eq $null)     >  False

根据iRon's linkCount是一个更好的测试,可以查看哈希表/数组是否为空。 Related 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

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

Get-Member行为不同 - 请参阅Mathias's explanation

$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

变量的Length属性不同。但哈希表没有Length属性 - see mjolinar's answer

$a.Length   > 0
$h.length   > 1

结合Ansgar's link解释了if语句中的不同行为,因为它似乎隐含地获取了Length属性。它还允许我们这样做:

if ($a.Length -eq $true)    >  False
if ($h.Length -eq $true)    >  True

使用[String] .Net类的IsNullOrEmpty method提供与$null相比的不同输出,我假设因为这也依赖于Length

if ([string]::IsNullOrEmpty($a))    > True
if ([string]::IsNullOrEmpty($h))    > False