[C#]關於Distinct與重寫IEqualityComparer時得知道的二三事

咱們在想對一個可枚舉的對象集合進行去重操做時,通常第一個想到的就是就是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對象了,成功實現了去重。

 

            `           

相關文章
相關標籤/搜索