可为空CustomClass重写Equals遇空指针及扩展方法适配问题求解决方案
解决CustomClass Equals方法空对象调用与非空逻辑统一问题
核心思路
通过统一静态方法作为相等判断的逻辑入口,让实例Equals方法、扩展方法都复用这一逻辑,同时处理null场景,避免空引用异常,且保证非空对象调用Equals时执行自定义逻辑。
具体实现步骤
- 编写静态Equals方法(核心逻辑)
这个方法负责处理所有null情况和自定义相等判断,是所有相等判断的统一入口:
public class CustomClass { // 示例属性,根据实际业务替换 public int Id { get; set; } public string Name { get; set; } = string.Empty; public static bool Equals(CustomClass? a, CustomClass? b) { // 两个引用相同(包括都为null) if (ReferenceEquals(a, b)) return true; // 其中一个为null,另一个不为null if (a is null || b is null) return false; // 自定义相等判断逻辑,根据实际属性调整 return a.Id == b.Id && a.Name == b.Name; } }
- 重写实例Equals方法
让实例的Equals调用静态方法,确保非空对象调用时执行自定义逻辑:
public override bool Equals(object? obj) { return Equals(this, obj as CustomClass); }
- 添加扩展方法处理null调用
当调用者为null时,通过扩展方法触发静态逻辑,避免空引用异常:
public static class CustomClassExtensions { public static bool Equals(this CustomClass? customClass, object? obj) { return CustomClass.Equals(customClass, obj as CustomClass); } }
- 配套重写GetHashCode(必选)
根据Equals的判断逻辑重写GetHashCode,保证两者一致性(否则可能导致字典等集合行为异常):
public override int GetHashCode() { // 结合参与相等判断的属性计算哈希码 return HashCode.Combine(Id, Name); }
- 可选:重载==和!=运算符
让相等判断更直观,同时复用静态逻辑:
public static bool operator ==(CustomClass? a, CustomClass? b) { return Equals(a, b); } public static bool operator !=(CustomClass? a, CustomClass? b) { return !Equals(a, b); }
效果验证
- 当对象为null时:
((CustomClass?)null).Equals(someObj)会调用扩展方法,执行静态逻辑,不会抛异常 - 当对象非空时:
new CustomClass().Equals(someObj)会调用重写的实例Equals方法,同样执行静态逻辑,而非默认的Object.Equals
内容的提问来源于stack exchange,提问作者Ben Robinson
相关产品推荐
相关产品推荐

