使用案例:在集合、字典在去重或是加入的操作的时候会调用元素的这两个方法(默认被调用,可以反编译查看),查找是否已经存在相同的元素了。有时候需要自定义查找规则,这时候就需要重写这两个方法了。
1.GetHashCode 方法的作用,提供快速查询对象。获取对象的hashcode,返回一个int值,默认是调用Object.GetHashCode()的哈希函数,可以被重写。这个函数的作用是在哈希集合查找是否存在相同的key的元素。
ps:
哈希函数的特点之一就是,哈希值相同的两个对象,输入值不一定相同,比如,A的哈希值1,B的哈希值也可能是1,但是两个对象不是同一个对象,这就是为什么有了下面的说法。重写的时候最好都重写Equals和GetHashCode两个方法。
2.微软推荐,重写其中的一个方法的同时也要重写另一个方法。
为什么这样呢?原因是在哈希字典中,当加入一个元素的时候,会先调用元素的GetHashCode得到一个值,判断这个值,是否已经存在keys中,如果不存在就加入,如果存在还要调用Equals方法进一步判断key对应的值是否相同。也就是两个方法是可能被一起调用,调用顺序:GetHashCode>Equals,简单的说就是GetHashCode是为了判断key是否相同,Equals是为了判断值是否相同。如果key相同就会调用equal方法判断是否值也相同(规则就是重写的方法)。
1 using System; 2 using System.Collections; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 7 namespace Demo 8 { 9 public class HashCodeDemo 10 { 11 12 public void IsEqual() 13 { 14 var list = new List<Student>() 15 { 16 new Student { Age = 1, Name = "1" }, 17 new Student { Age = 1, Name = "2" }, 18 new Student { Age = 2, Name = "2" }, 19 new Student { Age = 2, Name = "2" } 20 }; 21 22 //排序的时候会调用重写的规则方法来比较元素是否相同了 23 list = list.Distinct().ToList(); 24 25 } 26 27 } 28 29 30 public class Student 31 { 32 public int Age { get; set; } 33 public string Name { get; set; } 34 35 /// <summary> 36 /// 用来判断两个元素是否相同 37 /// </summary> 38 /// <param name="obj"></param> 39 /// <returns></returns> 40 public override bool Equals(object obj) 41 { 42 Console.WriteLine("Equals"); 43 if (obj == null || GetType() != obj.GetType()) return false; 44 45 if (obj is Student) 46 // 自定义的比较规则 47 return Age == ((Student)obj).Age && Name == ((Student)obj).Name; 48 49 return true; 50 51 } 52 53 /// <summary> 54 /// 这个方法的作用就是为了快速查找的使用, 返回一个int值,来判断集合或是字典中是否存在相同的key 55 /// </summary> 56 /// <returns></returns> 57 public override int GetHashCode() 58 { 59 Console.WriteLine("GetHashCode"); 60 return this.Age.GetHashCode(); 61 } 62 63 } 64 65 }