【问题标题】:Comparing an Entity比较实体
【发布时间】:2016-05-03 17:29:31
【问题描述】:

我已经构建了一个实体,我采用了一个实例化实体和一个修改后的实体。这允许我保存初始数据,与修改后的数据进行比较。问题是,理想的方法是什么?我应该实现IEquatable 作为Object.Equals 的覆盖还是实现ICompare?我最初的实现是:

var properties = typeof(TEntity).GetProperties();
foreach(var property in properties)
{
    var initialEntity = original.GetType().GetProperty(property.Name).GetValue(original, null);    
    var modifiedEntity = userChange.GetType().GetProperty(property.Name).GetValue(userChange, null);

    if(initialEntity.Equals(modifiedEntity) == false && !ignore.Contains(property.Name))
    {
        // Do Something
    }
}

我的理解是它会返回一个boolean,在这种情况下它也会比较 Value Equality,我假设它是基于引用相等性进行比较的。

因为它从不区分,所以在任何情况下都保持平等。

【问题讨论】:

  • 确定不是同一个实例?
  • 那些是 linq 实体吗?如果是,那么 ObjectStateManager 已经保存了您对其所做的所有更改
  • 您可能想查看我几个月前发布的一些项目:TrackerDog。它已经完成了您想要实现的目标!

标签: c# asp.net generics reflection


【解决方案1】:

最简单的答案:

  • 如果您需要测试相等性,请实现 IEquatable<T> 并覆盖 Equals()GetHashCode()
  • 如果需要对对象进行排序,实现IComparable<T>

Object.Equals() 的默认实现确定一个对象使用的内存位置是否与另一个对象相同。这本质上是Object.ReferenceEquals(obj1, obj2) 所做的,但 dot net 需要您告诉它如何确定您创建的两个对象是否相等。

此外,Object.GetHashCode() 的默认实现是对象在内存中的位置的 32 位地址(或地址的一部分)。除非您重写它以生成一个哈希码,该哈希码是您在 Equals() 方法中比较的所有内容的函数,否则当您尝试将其存储在哈希集中或将其用作字典键时,您将得到意想不到的结果。

您可能需要同时实现两者,但在您的情况下,IEquatable<T> 似乎是最紧迫的需求。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-04
    • 2013-10-31
    • 1970-01-01
    • 2018-05-14
    • 2011-11-13
    • 2016-08-17
    • 1970-01-01
    • 2023-01-18
    相关资源
    最近更新 更多