This isn't a question of True/False. You can test this using the Boolean operators $true
and $false
. I've used $h
as the empty hashtable @{}
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
Also not equal to automatic variable $null
:
if($a -eq $null) > False
if($h -eq $null) > False
As per iRon's link, Count
is a better test to see if a hashtable/array is empty. Related Length
The different behaviour will be related to the fundamental types.
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
It's to do with how the if
statement works and the Length
property, AFAICS. Below is my (admittedly shaky) understanding from multiple StackOverflow posts and external links.
Get-Member
behaviour is different - see 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
The Length
property of the variables is different. But the hashtable does not have a Length
property - see mjolinar's answer.
$a.Length > 0
$h.length > 1
Combining with Ansgar's link explains the different behaviors in the if
statement as it seems to be implicitly getting the Length
property . It also allows us to do this:
if ($a.Length -eq $true) > False
if ($h.Length -eq $true) > True
Using the IsNullOrEmpty method of the [String] .Net class gives different output compared to $null
, I assume because this also relies on the Length
.
if ([string]::IsNullOrEmpty($a)) > True
if ([string]::IsNullOrEmpty($h)) > False