咱們在想對一個可枚舉的對象集合進行去重操做時,通常第一個想到的就是就是Linq的Distinct方法。this
先定義一個類,而後使用Distinct方法去重spa
class Man { public int Age { get; set; } public string Name { get; set; } public string Adress { get; set; } public decimal Weight { get; set; } public decimal Height { get; set; } }
List<Man> list = new List<Man>() { new Man(){Age=21,Name="Adam",Adress="Shenzhen",Weight=60,Height=170}, new Man(){Age=21,Name="Adam",Adress="Shenzhen",Weight=60,Height=170} }; var distinct = list.Distinct();
然而去重獲得的distinct集合的Count依然爲二,集合裏依然存在兩個Adam。code
實際上,Distinct方法內進行比較的是聲明的引用,而不是對象屬性,就和對兩個屬性如出一轍的對象使用Equals()方法獲得的是False同樣。對象
所以咱們對對象集合使用Distinct方法時要使用重載Distinct<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer);blog
要使用這個方法,咱們得重寫IEqualityComparer接口,再使用Distinct方法:接口
public class ManComparer : IEqualityComparer<Man> { public bool Equals(Man x, Man y) { return x.Age == y.Age && x.Name == y.Name && x.Adress == y.Adress && x.Weight == y.Weight && x.Height == y.Height; } public int GetHashCode(Man obj) { return obj.GetHashCode(); } } var distinct = list.Distinct(new ManComparer());
然而,再一次,distinct集合內依然有兩個對象。ci
實際上,因爲直接獲取對象的HashCode,用HashCode進行比較的速度比 Equals 方法更快,get
所以IEqualityComparer內部會在使用 Equals 前先使用 GetHashCode 方法,在兩個對象的HashCode都相同時即刻判斷對象相等。string
而當兩個對象HashCode不相同時, Equals 方法就會被調用,對要比較的對象進行判斷。it
因爲在上例中list中的兩個引用其實是兩個不一樣的對象,所以HashCode一定不相同
因此要觸發Equlas方法,咱們須要改 GetHashCode ,讓它返回相同的常量
public class ManComparerNew : IEqualityComparer<Man> { public bool Equals(Man x, Man y) { return x.Age == y.Age && x.Name == y.Name && x.Adress == y.Adress && x.Weight == y.Weight && x.Height == y.Height; } public int GetHashCode(Man obj) { return 1; } } var distinct = list.Distinct(new ManComparerNew());
如今distinct集合中就只有一個Man對象了,成功實現了去重。
`