代码之家  ›  专栏  ›  技术社区  ›  Imad

Linq扩展方法没有使用Object类的Equals

  •  0
  • Imad  · 技术社区  · 1 年前

    我正在编写一个简单的应用程序,比较两个excel文件并返回结果。这种比较需要在少数列上进行,而不是在所有列上进行。我在excel中创建了一个表示行的类,并重写了Equals方法,如下所示

    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;
        }
    } 
    

    当我使用以下内容比较excel时 Linq 方法,我从issuesInNewFile中获取所有记录。

    issuesInNewFile.Except(benchmarkIssues).ToList();
    

    这是比较的完整代码

    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();
    }
    

    为了测试这一点,我只对excel中的2行进行了更改,但我得到了两个文件的串联。

    我是否编写了任何不正确的代码或我对 Equals 方法错误?

    1 回复  |  直到 1 年前
        1
  •  0
  •   SomeBody    1 年前

    Equals方法有两个问题:首先,如果另一个对象不是类型,它会抛出异常 Issue ,这对大多数开发人员来说是一种意想不到的行为。其次,如果重写Equals,则应始终重写GetHashcode。重要的是,GetHashcode为Equals返回true的两个变量提供相同的结果。您还可以实现 IEquatable<Issue> 让你的代码更有表现力,因为每个人都可以看到,这个类是为了与其他问题进行比较。代码可能如下所示:

    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();
        }
    }