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

C#基类重载==运算符后,派生类如何实现引用相等比较

解决C#基类与派生类相等运算符的差异化需求

核心思路

要实现基类用自定义值相等、派生类用引用相等,关键是:

  • 基类的相等逻辑仅对自身类型生效,对派生类实例自动降级为引用相等判断
  • 派生类显式重载相等运算符,强制使用引用相等逻辑

基类Hex的正确实现

修改基类的==运算符和Equals方法,增加类型匹配检查,确保只有当两边都是Hex类型(非派生类)时才使用坐标比较:

public class Hex
{
    public int Q { get; }
    public int R { get; }
    public int S { get; }

    public Hex(int q, int r, int s)
    {
        Q = q;
        R = r;
        S = s;
    }

    public static bool operator ==(Hex left, Hex right)
    {
        // 处理null边界情况
        if (ReferenceEquals(left, null))
            return ReferenceEquals(right, null);
        if (ReferenceEquals(right, null))
            return false;
        
        // 仅当两边类型完全匹配时,才用坐标判断相等
        if (left.GetType() != right.GetType())
            return ReferenceEquals(left, right);
        
        return left.Q == right.Q && left.R == right.R && left.S == right.S;
    }

    public static bool operator !=(Hex left, Hex right)
    {
        return !(left == right);
    }

    public override bool Equals(object obj)
    {
        if (obj is not Hex hexObj)
            return false;
        // 同样检查类型是否完全匹配
        if (GetType() != hexObj.GetType())
            return ReferenceEquals(this, hexObj);
        return Q == hexObj.Q && R == hexObj.R && S == hexObj.S;
    }

    public override int GetHashCode()
    {
        // 基于坐标生成哈希码,与值相等逻辑一致
        return HashCode.Combine(Q, R, S);
    }
}

派生类HexWithMeta的实现

显式重载==、!=运算符,直接使用引用相等判断;同时重写Equals和GetHashCode保持逻辑一致性:

public class HexWithMeta : Hex
{
    public int OwnerId { get; }

    public HexWithMeta(int q, int r, int s, int ownerId) : base(q, r, s)
    {
        OwnerId = ownerId;
    }

    // 重载==运算符,强制使用引用相等
    public static new bool operator ==(HexWithMeta left, HexWithMeta right)
    {
        return ReferenceEquals(left, right);
    }

    public static new bool operator !=(HexWithMeta left, HexWithMeta right)
    {
        return !ReferenceEquals(left, right);
    }

    public override bool Equals(object obj)
    {
        // 引用相等判断
        return ReferenceEquals(this, obj);
    }

    public override int GetHashCode()
    {
        // 返回基于引用的哈希码,与引用相等逻辑一致
        return System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(this);
    }
}

效果验证

  • 两个坐标相同的Hex实例比较:new Hex(1,2,-3) == new Hex(1,2,-3) 返回true,符合预期
  • 两个坐标相同但引用不同的HexWithMeta实例比较:new HexWithMeta(1,2,-3,1) == new HexWithMeta(1,2,-3,1) 返回false,符合预期
  • Hex实例与HexWithMeta实例比较:new Hex(1,2,-3) == new HexWithMeta(1,2,-3,1) 返回false,因为类型不匹配,走引用相等判断

扩展说明

如果后续有其他派生类需要使用引用相等,只需按照HexWithMeta的模式,重载==、!=并重写Equals和GetHashCode即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 11:40:38