Why is $false -eq "" true?
The following code segments output true:
$x = ($false -eq "")
Write-Host $x
$x = ($false -eq 0)
Write-Host $x
Since $false and "" are different data types, shouldn't it automatically equal false?
Solution 1:
When doing comparison operations, PowerShell will automatically attempt to coerce the object on the right-hand side of the operator to match the type on the left-hand side.
In the case of coercing [string]
to [bool]
, any non-null string will evaluate as $true
, and a null string will evaluate as $false
. See blog post Boolean Values and Operators for more information about automatic conversion of different data types to boolean values.
This sometimes leads to unexpected results:
PS C:\> [bool]"$false"
True
The string value of $false
is 'False', which is a non-null string and evaluated to $true
when cast back to [bool]
.
It also makes comparison operations non-commutative when the operands are of different data types:
PS C:\> '' -eq $false
False
PS C:\> $false -eq ''
True
In the first comparison the value $false
is auto-cast to a string in order to match the type of the first operand (''
), so you're actually comparing '' -eq 'False'
, which evaluates to $false
.
In the second comparison the string ''
is auto-cast to a boolean, again in order to match the type of the first operand ($false
), so this time you're actually comparing $false -eq $false
, which evaluates to $true
.
Solution 2:
Just sharing one experience here which might be worth noting when we convert a string value to boolean:
What I was doing is reading a boolean string value from a configuration file which was getting stored in a variable as shown below:
$valueReadFromFile = "false"
Now, I wanted to convert it to Boolean value. Since I was not aware of Convert
class in PowerShell I used casting instead as shown below in a bool condition of if
block:
if([bool]$valueReadFromFile -eq $true)
{
echo "This message shouldn't get printed in current scenario"
}
But I was on a wrong turn. Everytime below message was getting printed because non-empty string in PowerShell gets casted to literal boolean value $true
:
This message shouldn't get printed in current scenario
When my program started to behave incorrectly then I explored more and came to know about convert class. I fixed my code as below:
$actualBoolValue = [System.Convert]::ToBoolean($valueReadFromFile.Trim())