在我開始,所有的代碼樣本這裏,我在Mono環境測試,並沒有在GetHashCode
實現一個顯着的區別:在C#中實現GetHashCode。空值處理
string.Empty.GetHashCode(); // returns 0 in Mono 3.10
string.Empty.GetHashCode(); // returns 757602046 in .NET 4.5.1
我在我的基礎上通過@JonSkeet並在此SO Answer實施他還建議使用零散列代碼作爲NULL值(不知道該如何散列它們)。
我通常使用0作爲null的有效哈希碼 - 這與忽略該字段不同。
因此,有以下implementation(單聲道3.10):
public class Entity {
public int EntityID { get; set; }
public string EntityName { get; set; }
public override int GetHashCode() {
unchecked {
int hash = 15485863; // prime number
int multiplier = 1299709; // another prime number
hash = hash * multiplier + EntityID.GetHashCode();
hash = hash * multiplier + (EntityName != null ? EntityName.GetHashCode() : 0);
return hash;
}
}
}
這是很容易找到例如碰撞
var hash1 = new Entity { EntityID = 1337, EntityName = "" }.GetHashCode();
var hash2 = new Entity { EntityID = 1337, EntityName = null }.GetHashCode();
bool equals = hash1 == hash2; // true
我可以用一些其他數字代替空值0,但它不會解決問題,還有一個機會,一些哈希(串),輸出會產生這樣的數字,我會得到另一個碰撞。
我的問題:如何使用上面的示例中的算法處理空值?
您將始終有碰撞在哈希碼中。這就是哈希碼的本質。出於這個原因,你**總是**實現一個類的equals函數,該類生成一個哈希代碼來驗證返回相同哈希代碼的兩個對象是否真的相等。 – Nitram
我的示例中的對象具有相同哈希代碼的不同狀態。我錯過了什麼嗎? –
忽略這個建議,不要使用'0'來代替'null',而要使用別的東西,因爲'String.Empty'在單聲道上也給了你'0',而且@Nitram說你不能總是避免碰撞。 – Habib