重写Equals后Linq Except未生效,Excel行对比异常排查
问题原因与解决方法
你的问题出在只重写了Equals方法,但没有重写GetHashCode方法,这是使用Linq集合操作(如Except)时的典型错误。
为什么会出现这个现象?
Linq的Except方法依赖哈希表优化性能:
- 首先根据对象的
GetHashCode结果分组 - 只有哈希码相同的对象,才会进一步调用
Equals做精确比较
你没有重写GetHashCode,.NET会使用默认的引用哈希码(每个新实例的哈希码都不同)。这导致Except认为两个集合里的所有对象都是不同的,所以:
issuesInNewFile.Except(benchmarkIssues)返回issuesInNewFile的全部记录benchmarkIssues.Except(issuesInNewFile)返回benchmarkIssues的全部记录
最终拼接结果就是两个文件的所有记录,和测试场景预期不符。
解决方法
在Issue类中同时重写GetHashCode方法,哈希码的计算必须基于Equals方法中用到的所有属性,保证相等的对象一定有相同的哈希码。
修正后的Issue类代码:
public class Issue { public string Severity { get; set; } public string Line { get; set; } public string Type { get; set; } public string Component { get; set; } public string Location { get; set; } public string Status { get; set; } public BenchmarkCompareResult BenchmarkCompareResult { get; set; } public override bool Equals(object obj) { if (obj is not Issue issue) return false; return Severity == issue.Severity && Line == issue.Line && Type == issue.Type && Component == issue.Component && Location == issue.Location && Status == issue.Status; } // 重写GetHashCode,基于Equals中用到的属性计算 public override int GetHashCode() { // .NET Core/.NET 5+推荐使用HashCode.Combine return HashCode.Combine(Severity, Line, Type, Component, Location, Status); // 如果是.NET Framework,可以手动计算: // int hash = 17; // hash = hash * 23 + (Severity?.GetHashCode() ?? 0); // hash = hash * 23 + (Line?.GetHashCode() ?? 0); // hash = hash * 23 + (Type?.GetHashCode() ?? 0); // hash = hash * 23 + (Component?.GetHashCode() ?? 0); // hash = hash * 23 + (Location?.GetHashCode() ?? 0); // hash = hash * 23 + (Status?.GetHashCode() ?? 0); // return hash; } }
额外优化建议
在Equals方法开头添加类型检查(obj is not Issue issue),避免强制转换时出现InvalidCastException。
内容的提问来源于stack exchange,提问作者Imad
相关产品推荐
相关产品推荐

