需依赖IEqualityComparer比较时,是否应在Equals()和GetHashCode()中抛异常?
解决方案:重写Equals/GetHashCode抛异常是合理且推荐的做法
你的场景下,重写Equals()和GetHashCode()来阻止默认行为并提示正确用法,是完全合理的选择——毕竟默认实现的误导性结果带来的隐性bug,比直接抛出异常的显性问题难排查得多。
以下是具体的实践建议:
1. 调试/测试环境:用断言快速阻断错误调用
在开发阶段,用Debug.Assert直接触发警告,让开发者立刻意识到用错了方式,同时发布环境可保留默认实现作为兜底(仅建议特殊兼容场景使用):
public override bool Equals(object obj) { Debug.Assert(false, "禁止直接调用Equals,请使用CustomEqualityComparer进行相等性比较"); return base.Equals(obj); } public override int GetHashCode() { Debug.Assert(false, "禁止直接调用GetHashCode,请使用CustomEqualityComparer计算哈希码"); return base.GetHashCode(); }
这种方式能在开发测试阶段快速发现问题,不影响发布后的程序运行,但如果发布环境中仍有错误调用,还是会产生误导性结果。
2. 发布环境:直接抛出明确异常(更严谨)
如果业务上绝对不允许默认的相等性判断被使用,直接抛出InvalidOperationException,让错误立刻暴露,避免隐性bug:
public override bool Equals(object obj) { throw new InvalidOperationException("该类型的相等性比较必须通过CustomEqualityComparer完成,请注入对应的比较器后再操作"); } public override int GetHashCode() { throw new InvalidOperationException("该类型的哈希码计算必须通过CustomEqualityComparer完成,请注入对应的比较器后再操作"); }
虽然这种方式看起来"强硬",但能彻底杜绝错误调用带来的潜在问题(比如字典键匹配错误、集合去重失败等),让问题在第一时间被发现和修复。
3. 额外优化:配合注释和辅助方法引导正确用法
- 给类加上XML注释,明确标注禁止直接调用
Equals和GetHashCode,指定必须使用的比较器类型:/// <summary> /// 注意:该类型禁止直接调用Equals()和GetHashCode(),请使用CustomEqualityComparer进行相等性判断 /// </summary> public class YourClass { // ...类成员 } - 在类内部提供一个实例方法,接收比较器参数来完成相等性判断,进一步降低使用门槛:
public bool Equals(YourClass other, CustomEqualityComparer comparer) { return comparer.Equals(this, other); }
内容的提问来源于stack exchange,提问作者Matt Allwood
相关产品推荐
相关产品推荐

