1

我有来自具有身份 ID 字段的 SQL Server 数据库的 POCO。我想实现 IEquatable 所以我可以检查它们是否是相同的记录,使用.Contains()List<T>

假设我永远不需要比较未保存的实例,仅使用以下方法就足够了:

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

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

我正要这样做,但只是想检查一下,因为我不是 100% 确定 GetHashCode 与它有什么关系,或者是否有任何其他考虑因素(例如“未保存的实例”,其中我可以丢弃)我不知道。

4

2 回答 2

4

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

至于比较您的 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(); 
}

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

于 2013-04-24T20:42:58.133 回答
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)

于 2013-04-24T20:47:31.313 回答