集合去重
用实现IEqualityComparer<T>接口的类,来进行重复元素的消除。
class Program { static void Main(string[] args) { //集合去重 //List<int> list = new List<int>() { 1,2,3,4,4,4,5,5,6}; //list.Distinct().ToList().ForEach(s => Console.WriteLine(s)) ; Person p1 = new Person() { Name="兰陵王",Age=19}; Person p2 = new Person() { Name="兰陵王",Age=19}; Person p3 = new Person() { Name="亚瑟",Age=20}; Person p4 = new Person() { Name="兰陵王",Age=29}; Person p5 = new Person() { Name="王昭君",Age=21}; Person p6 = new Person() { Name="王昭君",Age=21}; Person p7 = new Person() { Name = "兰陵王", Age = 29 }; Person p8 = new Person() { Name = "王昭君", Age = 22 }; List<Person> list = new List<Person>() { p1,p2,p3,p4,p5,p6,p7,p8}; //list.Distinct(new Compare()).ToList().ForEach(s => Console.WriteLine(s.ToString())); list.Distinct(new Compare<Person>()).ToList().ForEach(s => Console.WriteLine(s.ToString())); Console.ReadKey(); } } public class Person { public string Name { get; set; } public int Age { get; set; } public override string ToString() { return string.Format("{0}\t{1}", this.Name, this.Age); } } public class Compare : IEqualityComparer<Person> { public bool Equals(Person x, Person y) { bool b= (x.Name == y.Name)&&(x.Age==y.Age); return b; } public int GetHashCode(Person obj) { return obj.Name.GetHashCode(); } } public class Compare<T> : IEqualityComparer<T> { public bool Equals(T x, T y) { PropertyInfo[]properties= x.GetType().GetProperties(); bool mark = true; foreach (var property in properties) { mark = mark && property.GetValue(x).Equals(property.GetValue(y)); //不能用== } return mark; } public int GetHashCode(T obj) { PropertyInfo[] properties = obj.GetType().GetProperties(); //return properties[0].GetValue(obj).ToString().GetHashCode(); //return (properties[0].GetValue(obj).ToString()+properties[1].GetValue(obj)).GetHashCode(); //return obj.GetHashCode(); int a = (properties[0].GetValue(obj).ToString() + properties[1].GetValue(obj)).GetHashCode(); int b= obj.GetHashCode();//只要不是同一个对象,产生的HashCode就不一样(即使它所有属性都相同)。 return a; } }
IEqualityComparer<T>接口的两个方法,一个Equals,一个GetHashCode,先用GetHashCode做第一遍过滤,如果HashCode就不一样,就不会剔除,也不会进行Equals方法。如有一样,再用Equals方法进行比较。
其实如果把对象的所有属性作为HashCode,Equals直接返回true就可以了 。
最后的版本
using System; using System.Collections.Generic; using System.Configuration; using System.Data.SqlClient; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace sqlTest { class Program { static void Main(string[] args) { //集合去重 //List<int> list = new List<int>() { 1,2,3,4,4,4,5,5,6}; //list.Distinct().ToList().ForEach(s => Console.WriteLine(s)) ; Person p1 = new Person() { Name = "兰陵王", Age = 19 }; Person p2 = new Person() { Name = "兰陵王", Age = 19 }; Person p3 = new Person() { Name = "亚瑟", Age = 20 }; Person p4 = new Person() { Name = "兰陵王", Age = 29 }; Person p5 = new Person() { Name = "王昭君", Age = 21 }; Person p6 = new Person() { Name = "王昭君", Age = 21 }; Person p7 = new Person() { Name = "兰陵王", Age = 29 }; Person p8 = new Person() { Name = "王昭君", Age = 22 }; List<Person> list = new List<Person>() { p1, p2, p3, p4, p5, p6, p7, p8 }; //list.Distinct(new Compare()).ToList().ForEach(s => Console.WriteLine(s.ToString())); //第一步 // list.Distinct(new Compare<Person>()).ToList().ForEach(s => Console.WriteLine(s.ToString())); //第二步 //最终版本 list.MyDistinct((s => s.Name), (s => s.Age)).ToList().ForEach(s => Console.WriteLine(s.ToString())); Console.ReadKey(); } } public class Person { public string Name { get; set; } public int Age { get; set; } public override string ToString() { return string.Format("{0}\t{1}", this.Name, this.Age); } } #region 第一步 //public class Compare : IEqualityComparer<Person> //{ // public bool Equals(Person x, Person y) // { // bool b = (x.Name == y.Name) && (x.Age == y.Age); // return b; // } // public int GetHashCode(Person obj) // { // return obj.Name.GetHashCode(); // } //} #endregion #region 第二步 //public class Compare<T> : IEqualityComparer<T> //{ // public bool Equals(T x, T y) // { // PropertyInfo[] properties = x.GetType().GetProperties(); // bool mark = true; // foreach (var property in properties) // { // mark = mark && property.GetValue(x).Equals(property.GetValue(y)); // } // return mark; // } // public int GetHashCode(T obj) // { // PropertyInfo[] properties = obj.GetType().GetProperties(); // //return properties[0].GetValue(obj).ToString().GetHashCode(); // //return (properties[0].GetValue(obj).ToString()+properties[1].GetValue(obj)).GetHashCode(); // //return obj.GetHashCode(); // int a = (properties[0].GetValue(obj).ToString() + properties[1].GetValue(obj)).GetHashCode(); // int b = obj.GetHashCode(); // int c = properties[0].GetValue(obj).ToString().GetHashCode(); // int d = properties[0].GetValue(obj).GetHashCode(); // return c; // } //} #endregion #region 最后的版本 public static class CommonHelper { public static IEnumerable<T> MyDistinct<T, C, W>(this IEnumerable<T> source, Func<T, C> getfield, Func<T, W> getfield1) { return source.Distinct(new Compare<T, C, W>(getfield, getfield1)); } } public class Compare<T, C, W> : IEqualityComparer<T> { private Func<T, C> _getField; private Func<T, W> _getField1; public Compare(Func<T, C> getfield, Func<T, W> _getField1) { this._getField = getfield; this._getField1 = _getField1; } public bool Equals(T x, T y) { return EqualityComparer<W>.Default.Equals(_getField1(x), _getField1(y)); } public int GetHashCode(T obj) { return EqualityComparer<C>.Default.GetHashCode(this._getField(obj)); } } #endregion }