比较C#中相同对象的两个集合并查找新的、更改的或删除的记录

比较C#中相同对象的两个集合并查找新的、更改的或删除的记录,c#,collections,icomparer,iequatable,C#,Collections,Icomparer,Iequatable,我有两组相同的东西 public class MyClass { public int Id {get;set;} public string Name {get;set;} public int Age{get;set;} public string SSN{get;set;} } 我有两个基于MyClass的集合(colA和colB),我想通过比较它们来找到新的、更改的或删除的记录。我的出发点是 var diff = colA.Except(colB); 但这给

我有两组相同的东西

 public class MyClass
 { 
  public int Id {get;set;}
  public string Name {get;set;}
  public int Age{get;set;}
  public string SSN{get;set;}
}
我有两个基于MyClass的集合(colA和colB),我想通过比较它们来找到新的、更改的或删除的记录。我的出发点是

  var diff = colA.Except(colB);
但这给了我错误的结果,实际上返回了整个可乐

然后我在MyClass中做了以下更改

 public Class MyClass
 {
 
    // Properties 
    public int Id {get;set;}
    public string Name {get;set;}
    public int Age{get;set;}
    public string SSN{get;set;}
  
  // Added override versions of following 
  
   public override int GetHashCode()
   {

       unchecked
       {
          return
            this.Id.GetHashCode();

       }
   }
   public override bool Equals(object obj)
   {
    var data = obj as MyClass;

      if (   (this.Id??0).Equals(data.Id ?? 0) 
          && (this.Age??0).Equals(data.Age ?? 0) 
          && (this.Name??string.Empty).Equals(data.Name ?? string.Empty)
          && (this.SSN??string.Empty).Equals(data.SSN ?? string.Empty) 
          )
                return true;

            return false;
   }
  
 }
为了避免在NULL上失败,我在不同的字段上应用了通过的NULL合并


我的问题是,这是最好的方法还是有更好的方法?以及如何更改此方法以获得字段级别的更改?

据我所知,最佳做法是在GetHashCode()和Equals(object obj)中使用相同的相等成员


如果使用resharper,您可以获得本手册的帮助:

我的方法如下:

  • 实现一个
    Diff
    方法,该方法类似于
    Equals
    返回在当前实例和传入实例之间不同的字段列表
  • Equals
    中使用该方法检查相等性。我可能会尝试实现
    IEquatable
    ,以实现一点类型安全性,因为它使代码更加清晰
  • 使用
    Except
    检查现有的新记录/已删除记录
  • 使用Linq和my
    Diff
    方法来提取哪些记录存在于两者中,但有更改-您需要选择您的“密钥”,我假定它是
    Id

规则是:相等对象的哈希代码必须相等,但是相等哈希代码并不一定意味着相等对象。这意味着可以将哈希代码计算建立在部分相等的基础上(尽管不一定推荐)。This.Id不能为null,因为它是值类型。这个年龄也一样。此外,data.Id不能为null,但data?.Id可以。是否需要它们在集合中的“相对位置”?也就是说,您是否希望做一些类似于源代码管理的事情?或者,是否应忽略在其他方面相同的移动项目?换句话说,
Except
会做你想做的事吗,或者你想知道在哪里添加或删除了某些内容吗?还有,“更改”,你怎么知道?是具有相同Id但其他字段不同的对象吗?或者我也可以不一样?