为什么自定义的“-eq”在Powershell中执行两次?

问题描述 投票:0回答:1

我在 PowerShell 中进行 OOP 编程时遇到了一个奇怪的问题。 具体来说,代码如下:

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

代码包含一个简单的自定义类x,并实现构造函数和一个Equals方法,该方法重载了-eq运算符。 但是,代码会打印两次“123”,为什么会发生这种情况?

在我的试验中,如果我将最后一行更改为“... -eq 2”,则只会打印一个“123”。看来如果第一次比较是 $false,它会再次尝试,并自动转换“$b”的类型(我也是通过打印 $b.GetType() 找到的)。

我猜powershell只是进行自动类型转换,如果第一次比较失败则重试。但我在官方指南中找不到这个语法。 另外,如何避免这种情况?

powershell oop operator-overloading
1个回答
1
投票

这是

-eq
运算符的源代码:

https://github.com/PowerShell/PowerShell/blob/ff3c8478983bfb566036362f8b629109fef8d180/src/System.Management.Automation/engine/LanguagePrimitives.cs#L629

正如 @SantiagoSquarzon 在评论中建议的那样,PowerShell 代码路径正在尝试两件事:

  • 2
    等于
    $xi1
    吗?
  • 如果没有,请尝试将
    2
    转换为
    x
    并进行比较

第二颗子弹发生在这里:

https://github.com/PowerShell/PowerShell/blob/ff3c8478983bfb566036362f8b629109fef8d180/src/System.Management.Automation/engine/LanguagePrimitives.cs#L697

    object secondConverted = LanguagePrimitives.ConvertTo(second, firstType, culture);
    return first.Equals(secondConverted);

换句话说,是这样的:

if( $xi1.Equals(2) )
{
   return $true
}
else
{
   $xi2 = [x] 2;
   return $xi1.Equals($xi2);
}
© www.soinside.com 2019 - 2024. All rights reserved.