[英]C# Implementing the Equals Method Correctly and How do I implement the GetHashCode Method
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Crystal_Message
{
class Person
{
private string firstName ="";
private string lastName= "";
private string phone="";
public Person(string firstName, string lastName, string phone)
{
this.FirstName = firstName;
this.LastName = lastName;
this.PhoneNumber = phone;
}
public string FirstName
{
get { return firstName; }
private set
{
if (string.IsNullOrWhiteSpace(value)){
throw new ArgumentNullException("Must Include First Name");
}
this.firstName = value;
}
}
public string LastName
{
get { return lastName; }
private set
{
if (string.IsNullOrWhiteSpace(value)){
throw new ArgumentNullException("Must Include Last Name");
}
this.lastName = value;
}
}
public string PhoneNumber
{
get { return phone; }
private set
{
if (string.IsNullOrWhiteSpace(value)){
throw new ArgumentNullException("Must Include Phone Number");
}
this.phone = value;
}
}
public override string ToString()
{
return "First Name: " + this.FirstName + " " + " Last Name: " + this.LastName + " " + " Phone Number: " + this.PhoneNumber;
}
public override bool Equals(object obj)
{
if(obj == null)
{
return false;
}
Person testEquals = obj as Person;
if((System.Object)testEquals == null)
{
return false;
}
return (this.firstName == testEquals.firstName) && (this.lastName == testEquals.lastName) && (this.phone == testEquals.phone);
}
/*
public override int GetHashCode()
{
return
}
*/
}
}
我遵循MSDN的指導方針。 兩個問題:
好吧,為了不遇到任何問題, GetHashCode
應該使用Equals
使用的所有成員,反之亦然。
所以在你的情況下:
public override int GetHashCode()
{
return firstName.GetHashCode() ^ lastName.GetHashCode() ^ phone.GetHashCode();
}
最好記住這兩種方法的目的是什么:使用equals你定義在哪種情況下你的類的兩個實例應該被視為,相等。 因此,如果在您的情況下給出iff名字,姓氏和電話號碼相等,那么這是正確的。 反過來,哈希方法用於對實例進行排序或分發,例如在哈希映射中。 它應該快速且足夠好以避免不必要的群集。 因此,您經常會看到值乘以散列函數中的素數。 您必須保證相等的對象具有相同的哈希碼,但反之則不然。 因此,不同的對象可能具有相同的哈希碼。
Filip的答案中提到的一種比簡單的哈希碼xor更常用的方法是使用更復雜的公式來組合它們。 將各個字段的哈希碼乘以不同的數字,例如:
public override int GetHashCode()
{
unchecked
{
return (firstName.GetHashCode() * 33 ^ lastName.GetHashCode()) * 33 ^ phone.GetHashCode();
}
}
(注意unchecked
關鍵字:此處需要整數溢出,而無聲環繞正是預期的行為。)
它可能不會對你正在處理的具體類型產生影響,但總的來說,它會更好。 考慮一個只包含兩個整數值的簡單類型。 還要考慮int
的GetHashCode()
實現只返回自己的值。 如果使用簡單的xor來組合這些值,那么普通代碼會產生大量的哈希沖突:最簡單的例子是每對兩個相同的值將產生相同的零哈希碼。
這里的計算實際上是由Tuple<T1, T2, T3>
完成的計算。 我沒有像微軟那樣寫它,但實際的計算和數字應該是一樣的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.