C# 集合 Distinct 對象屬性過濾

將字符串類型和整型分開處理(用到了表達式樹):測試

 

 

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;ui

/// <summary>
    /// 泛型集合或對象經過字符串類型屬性值比較是否相同
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class CollectionsPropertyComparer<T> : IEqualityComparer<T>
    {
        //委託
        Func<T, object> propertyValue = null;
        public CollectionsPropertyComparer(string propertyName)
        {
            PropertyInfo propertyInfo = typeof(T).GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty);
            if (propertyInfo == null)
            {
                throw new ArgumentException(string.Format("{0} is not the property of {1} type ", propertyName,typeof(T)));
            }orm

            //使用表達式樹獲取屬性值
            //參數
            ParameterExpression pe= Expression.Parameter(typeof(T), "obj");
            //建立一個訪問屬性
            MemberExpression me=  Expression.Property(pe, propertyInfo);
            //編譯返回lambda委託
            Type type = me.GetType();
            propertyValue = Expression.Lambda<Func<T,object>>(me,pe).Compile();
        }對象

        public bool Equals(T x, T y)
        {
            if (x == null)
                return y == null;索引

            //獲取對象屬性值進行比較
            object xValue = propertyValue(x);
            object yValue = propertyValue(y);字符串

            return xValue == yValue;
        }get

        public int GetHashCode(T obj)
        {
            if (obj == null)
                return 0;string

            object value = propertyValue(obj);it

            return value.GetHashCode();
        }
    }io

    /// <summary>
    /// 泛型集合或對象經過整數類型屬性值比較是否相同
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class CollectionsInt32PropertyComparer<T> : IEqualityComparer<T>
    {
        //委託
        Func<T, int> propertyValue = null;
        public CollectionsInt32PropertyComparer(string propertyName)
        {
            PropertyInfo propertyInfo = typeof(T).GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty);
            if (propertyInfo == null)
            {
                throw new ArgumentException(string.Format("{0} is not the property of type {1} ", propertyName, typeof(T)));
            }

            //使用表達式樹獲取屬性值
            //參數
            ParameterExpression pe = Expression.Parameter(typeof(T), "obj");
            //建立一個訪問屬性
            MemberExpression me = Expression.Property(pe, propertyInfo);
            //編譯返回lambda委託
            Type type = me.GetType();
            propertyValue = Expression.Lambda<Func<T, int>>(me, pe).Compile();
        }

        public bool Equals(T x, T y)
        {
            if (x == null)
                return y == null;

            //獲取對象屬性值進行比較
            int xValue = propertyValue(x);
            int yValue = propertyValue(y);

            return xValue == yValue;
        }

        public int GetHashCode(T obj)
        {
            if (obj == null)
                return 0;

            object value = propertyValue(obj);

            return value.GetHashCode();
        }
    }

 

 

測試示例:

public partial class TS : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                List<Student> students = new List<Student> {
                    new Student{ ID=1, StuID ="1", StuName="test1", Age=20},
                    new Student{ ID=1,StuID="1", StuName="test1", Age=21},
                    new Student{ ID=2,StuID="2", StuName="test2", Age=22},
                    new Student{ ID=3,StuID="3", StuName="test2", Age=22},
                    new Student{ ID=1,StuID="1", StuName="test2", Age=23}
                };


                var cp_studid= new CollectionsInt32PropertyComparer<Student>("ID");
                var cp_studname = new CollectionsPropertyComparer<Student>("StuName");

                //集合根據不一樣屬性過濾相同記錄
                var list_stuid = students.Distinct(cp_studid).ToList(); //集合索引爲:0,2,3
                var list_stuname = students.Distinct(cp_studname).ToList(); //集合索引爲:0,2

                //單個實體根據不一樣屬性比較相等
                var stuA = new Student { ID = 1, StuID = "1", StuName = "test1", Age = 20 };
                var stuB = new Student { ID = 1, StuID = "1", StuName = "test2", Age = 20 };
                var stuC = new Student { ID = 2, StuID = "2", StuName = "test2", Age = 20 };
                bool ab = cp_studid.Equals(stuA, stuB); //true
                bool ac = cp_studid.Equals(stuA, stuC);//false
                bool bc = cp_studname.Equals(stuB, stuC);//true

            }
        }
    }

    public class Student     {         public int ID { get; set; }         public string StuID { get; set; }         public string StuName { get; set; }         public int Age { get; set; }     }

相關文章
相關標籤/搜索