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

如何为PowerShell的-ceq运算符实现区分大小写的Equals方法

自定义类实现PowerShell区分大小写比较(-ceq)的方法

问题背景

在PowerShell中,自定义类的Equals方法会被-eq运算符调用。以下示例中,-eq实现了不区分大小写的比较:

class TestClass {
    hidden [String] $_Value
    TestClass([String]$Value) { $this._Value = $Value }
    [Bool] Equals($Test, [StringComparison]$StringComparison) {
        return $this._Value.Equals([String]$Test._Value, $StringComparison)
    }
    [Bool] Equals($Test) {
        return $this.Equals($Test, [StringComparison]::CurrentCultureIgnoreCase)
    }
}

$a1Lower = [TestClass]'a'
$b1Lower = [TestClass]'b'
$a2Lower = [TestClass]'a'
$a2Upper = [TestClass]'A'

$a1Lower -eq  $b1Lower # False
$a1Lower -eq  $a2Lower # True
$a1Lower -eq  $a2Upper # True

现在需要让-ceq运算符实现区分大小写的比较,期望执行以下代码时得到符合预期的结果:

$a1Lower -ceq $a2Lower # True
$a1Lower -ceq $a2Upper # False (原返回True,需修正)

解决方案

可以通过实现System.IEquatable<T>接口并分别定义大小写敏感和不敏感的比较逻辑来实现需求。PowerShell的-ceq运算符会优先调用IEquatable<T>接口的Equals方法,而-eq默认调用重写的Object.Equals方法,这样就能区分两种运算符的行为。

完整实现代码

class TestClass : System.IEquatable[TestClass] {
    hidden [String] $_Value

    # 构造函数
    TestClass([String]$Value) {
        $this._Value = $Value
    }

    # IEquatable<T>接口方法:区分大小写的比较(供-ceq调用)
    [Bool] Equals([TestClass]$other) {
        if ($null -eq $other) {
            return $false
        }
        # 使用Ordinal规则进行严格大小写敏感比较
        return $this._Value.Equals($other._Value, [StringComparison]::Ordinal)
    }

    # 重写Object.Equals:不区分大小写的比较(供-eq调用)
    [Bool] Equals($obj) {
        if ($null -eq $obj -or $obj -isnot [TestClass]) {
            return $false
        }
        $other = [TestClass]$obj
        return $this._Value.Equals($other._Value, [StringComparison]::CurrentCultureIgnoreCase)
    }

    # 重写GetHashCode:与不区分大小写的Equals逻辑保持一致
    [int] GetHashCode() {
        return $this._Value.ToLowerInvariant().GetHashCode()
    }

    # 重载==运算符:绑定到不区分大小写的比较(对应-eq)
    static [Bool] op_Equality([TestClass]$a, [TestClass]$b) {
        if ($null -eq $a) {
            return $null -eq $b
        }
        return $a.Equals($b)
    }

    # 重载!=运算符:绑定到不区分大小写的比较(对应-ne)
    static [Bool] op_Inequality([TestClass]$a, [TestClass]$b) {
        return -not ([TestClass]::op_Equality($a, $b))
    }
}

测试验证

$a1Lower = [TestClass]'a'
$b1Lower = [TestClass]'b'
$a2Lower = [TestClass]'a'
$a2Upper = [TestClass]'A'

# 验证-eq(不区分大小写)
$a1Lower -eq $b1Lower  # 输出: False
$a1Lower -eq $a2Lower  # 输出: True
$a1Lower -eq $a2Upper  # 输出: True

# 验证-ceq(区分大小写)
$a1Lower -ceq $a2Lower # 输出: True
$a1Lower -ceq $a2Upper # 输出: False(符合预期)

代码说明

  • 继承IEquatable<TestClass>:实现接口的Equals方法,使用StringComparison::Ordinal执行严格的大小写敏感比较,供-ceq运算符调用。
  • 重写Object.Equals:使用CurrentCultureIgnoreCase实现不区分大小写的比较,作为-eq运算符的默认逻辑。
  • 重载运算符:绑定op_Equality和op_Inequality到不区分大小写的比较逻辑,确保-eq和-ne的行为符合预期。
  • 重写GetHashCode:确保哈希值的计算逻辑与Object.Equals一致,避免集合操作中出现不一致的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 22:14:52