I meet a weird issue when I was doing some OOP programming in PowerShell. To be specific, the code is as below:
class x {
[int]$v1
x([int]$a1) {
$this.v1 = $a1
}
[bool] Equals([object]$b) {
Write-Host "123"
if ($b -is [int]) {
return $this.v1 -eq $b
}
return $false
}
}
$xi1 = [x]::new(2)
$bv = $xi1 -eq 3
The code contains a simple custom class x, and implement constructor and an Equals method, which overloads the -eq operator. However, the code will print "123" twice, why does it happen?
In my trials, if I change the last line to "... -eq 2", only one "123" would be printed. It seems if the first comparison be $false, it will try again, and convert the type of "$b" automatically (I find it via printing $b.GetType() as well).
I guess the powershell just do the auto-type-conversion and try again if the first comparison fails. But I cannot find this grammar in the official guide. Also, how to avoid this condition?
That is exactly right! When
$xi1 -eq 3fails,$xi1 -eq [x]3is attempted.You can observe the resulting type conversion operation with
Trace-Command:This behavior is encoded in the default equality comparison runtime binder, which can be found in
Binders.cc:Here we can see that if PowerShell can decide on a meaningful conversion (eg. by casting
[x]$b), then it'll try that and do a second comparison attempt against the results of that