C# distnict去重
阿新 • • 發佈:2020-08-18
在C#中,使用distinct的時候,會發現有些情況不好使,比如我是泛型集合的時候,發現沒去掉重複。這是因為對於引用型別,distinct裡的預設比較器比較的是其引用地址,程式中集合裡的每一個元素都是個新的例項,引用地址都是不同的,所以不會被作為重複記錄刪除掉。因此我們需要自定義比較器進行去重,實現指定條件去重複。
本章主要講解如何設計比較器。我們先來看看第一版:
public class JuryComparer: IEqualityComparer<T_S_SalesPointModel> { public bool Equals(T_S_SalesPointModel x, T_S_SalesPointModel y) {return x.ClientCode.Equals(y.ClientCode); } public int GetHashCode(T_S_SalesPointModel obj) { return 0; } }
使用的時候很簡單,.Distinct(new JuryComparer()),在distinct裡實例化這個引數傳入即可。
但是很快我們就發現一個問題,我們別的業務裡也需要用到這個,如果作為一個公共方法,顯然我是不能把model指定死的,所以有了第二版:
publicclass JuryComparer<T> : IEqualityComparer<T> { public bool Equals(T x, T y) { dynamic dx = x; dynamic dy = y; return dx.ClientCode.Equals(dy.ClientCode); } public int GetHashCode(T obj) { return0; } }
通過泛型T我們可以在方法內部不指定具體型別,這樣就方法就能自適應不同的model了。
然鵝,今天遇到一種情況,即,我們自定義的方法中,是通過ClientCode去做比較的,如果外部model中不存在這個Code,那我們就無法比較,因為方法會報錯,提示沒有這個屬性。也就是說我們的通用方法除了model需要通用以外,這個屬性,應該從外部傳進來,那麼如何實現呢,請看第三版:
public class JuryComparer<T> : IEqualityComparer<T> { private string _attribute; public JuryComparer(string attribute) { _attribute = attribute; } public bool Equals(T x, T y) { dynamic dx = x; dynamic dy = y; var vx = dx.GetType().GetProperty(_attribute).GetValue(dx, null); var vy = dy.GetType().GetProperty(_attribute).GetValue(dy, null); return vx.Equals(vy); } public int GetHashCode(T obj) { return 0; } }
通過建構函式傳參,我們將外部引數賦值給內部私有變數,最後在比較方法裡, 我們通過反射獲取屬性實現自適應。這樣外部就能通過這種方式實現呼叫:
.Distinct(new JuryComparer<TreeModel>("value"))
既可以傳入不同的model,又可以傳入不同的屬性。
以上。