.NET程序員都知道,若是咱們重寫一個類的Equals方法而沒有重寫GetHashCode,則VS會提示警告 :「***」重寫 Object.Equals(object o)但不重寫 Object.GetHashCode() 。html
可是,爲何重寫Equals必定要同時重寫GetHashCode呢?git
微軟的解釋是:程序員
GetHashCode 基於適合哈希算法和諸如哈希表的數據結構的當前實例返回一個值。 兩個相等的同類型對象必須返回相同的哈希代碼,才能確保如下類型的實例正確運行:算法
-
HashTable微信
-
Dictionaryide
-
SortDictionary函數
-
SortListpost
-
HybredDictionary測試
-
實現 IEqualityComparer 的類型
連接:http://msdn.microsoft.com/zh-cn/library/vstudio/ms182358.aspx
舉個例子:
重寫一個Person類
public class Person { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } /// <summary> /// 重寫Equals,若是Name與Age相等,就認爲類相等 /// </summary> /// <param name="obj"></param> /// <returns></returns> public override bool Equals(object obj) { if (obj == null) return false; if (obj is Person) { var person = obj as Person; return person.Age == this.Age && person.Name == this.Name; } else return false; } }
寫一個測試方法:
public static void Main(string[] args) { Person person1 = new Person() { Id = 1, Name = "AA", Age = 21 }; Person person2 = new Person() { Id = 2, Name = "AA", Age = 21 }; Console.WriteLine("person1與person2是否相等:" + person1.Equals(person2)); Console.Read(); }
結果:
返回的結果是true,這好像是咱們的重寫方法成功了。那咱們繼續寫一個測試方法吧。
ICollection<Person> list = new HashSet<Person>(); list.Add(person1); Console.WriteLine("List是否包含person1:"+list.Contains(person1)); Console.WriteLine("List是否包含person2:" + list.Contains(person2));
結果:
這時,就出問題了。既然person1與person2相等,list它包含person1,那也應該包含person2吧。緣由就是咱們沒有重寫GetHashCode方法,相同的對象沒有返回相等的HashCode。
咱們從新改變一下Person,讓它重寫GetHashCode方法。
public class Person { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } /// <summary> /// 重寫Equals,若是Name與Age相等,就認爲類相等 /// </summary> /// <param name="obj"></param> /// <returns></returns> public override bool Equals(object obj) { if (obj == null) return false; if (obj is Person) { var person = obj as Person; return person.Age == this.Age && person.Name == this.Name; } else return false; } public override int GetHashCode() { return this.Name.GetHashCode()^this.Age.GetHashCode(); } }
再運行兩個測試方法:
如今,方法都返回true了。
還有一個例子,若是將Person類看成鍵值放在字典中也會有問題,能夠參見:http://book.51cto.com/art/201109/292340.htm。
重寫GetHashCode的原則很簡單,只要能保證兩個相等的同類型對象返回相同的哈希代碼就OK了。
還找到一個說得比較好的地方,裏面第二個評論很精彩。http://blog.csdn.net/chenyuxu0/article/details/5886771