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
相关产品推荐
相关产品推荐

