You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell中自定义-eq运算符为何执行两次?

PowerShell自定义类Equals方法被重复调用的原因与解决

问题重现

你定义的自定义类实现了Equals方法,试图重载-eq运算符,但执行跨类型比较时出现了方法被两次调用的情况:

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  # 会两次输出"123"
$bv = $xi1 -eq 2  # 仅输出一次"123"

原因分析

这是PowerShell-eq运算符的双向比较逻辑导致的:

  1. 首次比较:调用左操作数([x]实例)的Equals方法,传入右操作数([int]类型的3),返回$false。
  2. 二次重试:由于首次比较失败,PowerShell会尝试将右操作数转换为左操作数的类型(你的类有接受[int]的构造函数,因此可以成功转换为[x]实例),再次调用左操作数的Equals方法,传入转换后的[x]实例,此时$b的类型变为[x],你的方法因未处理该类型返回$false,最终结果为$false。

而当比较$xi1 -eq 2时,首次调用Equals就返回$true,因此不会触发二次重试。

解决办法

方案1:完善Equals方法,处理同类型输入

在Equals方法中先判断输入是否为同类型实例,避免PowerShell触发不必要的转换重试:

class x {
    [int]$v1
    x([int]$a1) {
        $this.v1 = $a1
    }

    [bool] Equals([object]$b) {
        Write-Host "123"
        # 优先处理同类型实例比较
        if ($b -is [x]) {
            return $this.v1 -eq $b.v1
        }
        # 再处理int类型比较
        if ($b -is [int]) {
            return $this.v1 -eq $b
        }
        return $false
    }
}

方案2:实现IEquatable接口(推荐)

实现强类型的IEquatable<T>接口,让PowerShell明确比较逻辑,跳过默认的双向转换:

class x : System.IEquatable[x] {
    [int]$v1
    x([int]$a1) {
        $this.v1 = $a1
    }

    # 强类型Equals方法,优先被调用
    [bool] Equals([x]$b) {
        Write-Host "123"
        if ($null -eq $b) {
            return $false
        }
        return $this.v1 -eq $b.v1
    }

    # 重写object基类的Equals方法
    [bool] Equals([object]$b) {
        return $this.Equals($b -as [x])
    }
}

方案3:直接重载op_Equality运算符

通过重载静态的op_Equality方法,直接定义-eq的行为,完全绕过PowerShell的默认比较逻辑:

class x {
    [int]$v1
    x([int]$a1) {
        $this.v1 = $a1
    }

    static [bool] op_Equality([x]$a, [object]$b) {
        Write-Host "123"
        if ($b -is [int]) {
            return $a.v1 -eq $b
        }
        if ($b -is [x]) {
            return $a.v1 -eq $b.v1
        }
        return $false
    }
}

内容的提问来源于stack exchange,提问作者Roadelse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 22:55:25