1. 程式人生 > 實用技巧 >C# distnict去重

C# distnict去重

  在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指定死的,所以有了第二版:

    public
class 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) { return
0; } }

  通過泛型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,又可以傳入不同的屬性。

  以上。