IE在POCO身份字段上可以选择

时间:2013-04-24 20:34:51

标签: c# poco iequalitycomparer iequatable

我从SQL Server数据库中获得了具有身份ID字段的POCO。我想实现IEquatable,以便我可以检查它们是否是相同的记录,在.Contains()上使用List<T>等。

假设我永远不需要比较未保存的实例,只需使用以下方法实现:

    public bool Equals(MyClass other)
    {
        return this.ID == other.ID;
    }

    public override int GetHashCode()
    {
        return this.ID;
    }

我即将这样做,但只是想检查一下,因为我不能100%确定GetHashCode与它有什么关系,或者是否有任何其他注意事项(例如“未保存的实例”)我可以丢弃的一个,我不知道。

2 个答案:

答案 0 :(得分:4)

每当您覆盖GetHashCode()时(在实施Equals()时也应该这样做),您需要覆盖IEquatable<T>,以便依赖它的类,例如Dictionary<TKey, TValue> ,可以正确处理。这是烦人泄漏的内部细节之一。 More information

至于比较你的ID是否足以确定相等性,如果你绝对确定在所有情况下都应该认为具有相同ID的两个实体是等价的,那么就去做吧。这只是一个问题,只有您的应用程序的要求可以回答。我自己已经完成了很多次,几乎总是使用只读实体。

我会这样实现:

// IEquatable<MyClass> implementation
public bool Equals(MyClass other) 
{
  if (other == null) 
  {
    return false;
  }

  return this.ID == other.ID;
}

// Override of default Object.Equals()
public override bool Equals(object other) 
{
  return this.Equals(other as MyClass);
}

public override int GetHashCode()
{
  // Call ID.GetHashCode() because ID may not always be int,
  // and the ID type might have a more useful implementation
  // of GetHashCode() to offer.
  return this.ID.GetHashCode(); 
}

在这种情况下,您可能还应该覆盖==!=运算符。如果要区分具有相同ID的两个不同引用,则可以始终使用Object.ReferenceEquals()

答案 1 :(得分:1)

如果你的商业规则,当你的ID相等时你的对象彼此相等,那么你的对象就好了!

对象的哈希码表示每个具有不同状态的对象应返回不同的哈希码。这个哈希码不是唯一的,但我们可以尝试使它们尽可能不同。只需查看字符串"Hello".GetHashCode()"Goodbye".GetHashCode()的哈希码。

HashCode用于某些集合,例如System.Collections.Generic.Dictionary<K,V>System.Collections.Generic.HashSet<T>。通过使用此哈希码,这些字典可以通过使用此“唯一”哈希码非常快速地搜索和查找项目(几乎是O(1) - 操作)。通过使用实体字段的哈希码来计算此哈希码。

如果您实施IEquatable<T>.Equals,还要覆盖Equals(object)