为何自定义TilemapID类作为Dictionary键时相等判断失效?
问题原因分析
你的TilemapID类的Equals方法实现存在错误,导致两个id字符串完全相同的实例无法被判定为相等。
在当前的Equals方法中:
public override bool Equals(object obj) { return id.Equals(obj); }
这里调用的是string.Equals(object)方法,该方法会先检查传入的obj是否为string类型。当你在Dictionary中比较两个TilemapID实例时,传入Equals的obj是另一个TilemapID对象而非字符串,因此string.Equals会直接返回false,这就是调试时Equals返回false的核心原因。
修复方案
修改Equals方法,先判断对象类型,再比较内部的id字段:
public override bool Equals(object obj) { // 同一实例直接判定相等 if (ReferenceEquals(this, obj)) return true; // 对象为null或类型不匹配时判定不相等 if (obj is not TilemapID otherTilemapID) return false; // 比较id字段,同时处理id为null的情况 return string.Equals(id, otherTilemapID.id); }
进阶优化:实现IEquatable接口
为避免装箱操作、提升性能,建议同时实现IEquatable<TilemapID>接口:
[System.Serializable] public sealed class TilemapID : IEquatable<TilemapID> { public static readonly string[] ID_LIST = new string[] { "base", "foreground", "background" }; public string id; public TilemapID(string id) { this.id = id; } public override string ToString() { return id; } public override int GetHashCode() { // 处理id为null的情况,避免空引用异常 return id?.GetHashCode() ?? 0; } public override bool Equals(object obj) { return Equals(obj as TilemapID); } public bool Equals(TilemapID other) { if (other is null) return false; if (ReferenceEquals(this, other)) return true; return string.Equals(id, other.id); } public static explicit operator string(TilemapID id) => id.id; public static explicit operator TilemapID(string s) { for (int i = 0; i < ID_LIST.Length; i++) { if (ID_LIST[i].Equals(s)) return new TilemapID(ID_LIST[i]); } return null; } }
额外注意点
- 确保
GetHashCode的实现与Equals逻辑一致:修改后的GetHashCode增加了对id为null的处理,避免空引用异常。 - 显式类型转换操作符中,传入不在
ID_LIST中的字符串会返回null,使用时需注意空引用问题。
内容的提问来源于stack exchange,提问作者Heroshrine
相关产品推荐
相关产品推荐

