![](/img/trans.png)
[英]What would be implementation GetHashCode() for IEqualityComparer<double>
[英]What is the correct implementation for GetHashCode() for entity classes?
下面是一個覆蓋實體基類的Object.Equals()的示例實現,應用程序中的所有其他實體都從該實體基類派生。
所有實體類都具有屬性Id,它是一個可以為null的int。 (它是實體類對應的任何表的主鍵。)
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
return false;
if (base.Equals(obj))
return true;
return Id.HasValue && ((EntityBase) obj).Id.HasValue &&
Id.Value == ((EntityBase) obj).Id.Value;
}
鑒於Equals()的這種實現,你如何正確實現GetHashCode()?
如果您從已經覆蓋GetHashCode
內容派生,我將其實現為:
public override int GetHashCode()
{
unchecked
{
int hash = 37;
hash = hash * 23 + base.GetHashCode();
hash = hash * 23 + Id.GetHashCode();
return hash;
}
}
對於Id.GetHashCode(),Id的空值將返回0。
如果您的類只是從Object派生,我剛剛返回Id.GetHashCode()
-你不希望包括object.GetHashCode
在你的哈希碼實現,因為這基本上結束是對象的身份。
請注意,如果兩個實體都沒有Id,則您的相等定義將不會返回true
,但是將從兩個對象返回相同的哈希碼。 您可能希望考慮更改您的Equals實施。
Jon Skeet回答的是一個很好的解決方案,但是,您可能希望添加一個未經檢查的代碼塊以允許整數溢出
unchecked
{
int hash = ...;
return hash
}
https://msdn.microsoft.com/en-us/library/khy08726(v=vs.140).aspx
如果既未指定也未取消選中,則默認上下文取決於外部因素,例如編譯器選項。
我還想再次補充說,在POCO上使用base.GetHashCode()
會調用默認的object.GetHashCode
。 這絕對不是你想要的......
將類型用作哈希碼的一部分怎么樣?
這是一個很好的實施嗎?
public class Foo
{
public int Id { get; set; }
// other properties here
// ......
public override int GetHashCode()
{
int hash = 37;
hash = hash * 23 + typeof(Foo).GetHashCode();
hash = hash * 23 + Id.GetHashCode();
return hash;
}
}
如果Id
屬性在實例的生命周期中是不可變的(或者至少在其哈希需要使用的時間,例如當對象在地圖或其他需要哈希的集合中時GetHashCode()
則只能正確實現GetHashCode()
)。
假設它是,您可以使用Id
的值作為所有有效值的哈希值,然后使用固定哈希值為null。 我不記得最合適的是什么,但我會假設一個隨機選擇的null值(在編譯之前隨機選擇,而不是在運行時)或有效Id
值的中間值(即在0和int之間的中間值)。最大)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.