我从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与它有什么关系,或者是否有任何其他注意事项(例如“未保存的实例”)我可以丢弃的一个,我不知道。
答案 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)
。