I am writing a simple application that compare two excel files and return the result. This comparison needs to be done on few columns, and not on all the columns. I have created a class that represents row in excel, and overridden Equals method as below
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)
{
var issue = (Issue)obj;
return Severity == issue.Severity && Line == issue.Line && Type == issue.Type
&& Component == issue.Component && Location == issue.Location && Status == issue.Status;
}
}
When I compare excel using below Linq method, I get all the records from issuesInNewFile.
issuesInNewFile.Except(benchmarkIssues).ToList();
Here is full code of comparision
public static IList<Issue> CompareIssues(List<Issue> benchmarkIssues, List<Issue> issuesInNewFile)
{
var newIssues = issuesInNewFile.Except(benchmarkIssues).ToList();
var resolvedIssues = benchmarkIssues.Except(issuesInNewFile).ToList();
newIssues.ForEach(issue => issue.BenchmarkCompareResult = BenchmarkCompareResult.Added);
resolvedIssues.ForEach(issue => issue.BenchmarkCompareResult = BenchmarkCompareResult.Resolved);
return newIssues.Concat(resolvedIssues).ToList();
}
I have made changes to only 2 row in excel to test this but I am getting concatenation of two files instead.
Did I write any improper code or my understanding of Equals method is wrong?
>Solution :
There are two issues with your Equals method: First, it throws an exception if the other object is not of type Issue, which is an unexpected behaviour for most developers. Second, if you override Equals, you should always override GetHashcode. It is important the GetHashcode gives the same result for two variables where Equals returns true. You could also implement IEquatable<Issue> to make your code more expressive, because everyone can see that this class is made to compare to other issues. The code might look like this:
public class Issue : IEquatable<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 Issue issue)
{
return Equals(issue);
}
return false;
}
public bool Equals(Issue iusse)
{
if(issue is null)
{
return false;
}
return Severity == issue.Severity && Line == issue.Line && Type == issue.Type
&& Component == issue.Component && Location == issue.Location && Status == issue.Status;
}
public override int GetHashCode()
{
// compute the hashcode of a value tuple containing all relevant properties
return (Severity,Line,Type,Component,Location,Status).GetHashCode();
}
}