首页 > 其他分享 >Linq:Distinct()不能排除重复对象的解决方案

Linq:Distinct()不能排除重复对象的解决方案

时间:2022-08-30 16:47:42浏览次数:46  
标签:Name Distinct 解决方案 Branch Linq Student Gender Age ID

1.数据准备:

假设有几个重复数据,如下,(正常使用Distinct()方法,我们想要排除掉重复的对象)

using System.Collections.Generic;

namespace LINQTutorial
{
    public class Student
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public string Gender { get; set; }
        public string Branch { get; set; }
        public int Age { get; set; }
        public static List<Student> GetAllStudents()
        {
            return new List<Student>()
        {
            new Student { ID = 1001, Name = "玲玲", Gender = "Female",
                                         Branch = "CSE", Age = 20 },
            new Student { ID = 1002, Name = "张三", Gender = "Male",
                                         Branch = "ETC", Age = 21  },
            new Student { ID = 1003, Name = "李四", Gender = "Male",
                                         Branch = "CSE", Age = 21  },
            new Student { ID = 1004, Name = "王五", Gender = "Male",
                                         Branch = "CSE", Age = 20  },
            new Student { ID = 1005, Name = "珊珊", Gender = "Female",
                                         Branch = "ETC", Age = 20 },
            new Student { ID = 1006, Name = "涵涵", Gender = "Female",
                                         Branch = "CSE", Age = 21 },
            new Student { ID = 1007, Name = "钱六", Gender = "Male",
                                         Branch = "CSE", Age = 22  },
            new Student { ID = 1008, Name = "婷婷", Gender = "Female",
                                         Branch = "CSE", Age = 20  },
            new Student { ID = 1009, Name = "兰兰", Gender = "Female",
                                         Branch = "ETC", Age = 22 },
            new Student { ID = 1010, Name = "黄九", Gender = "Male",
                                         Branch = "ETC", Age = 21 },
             new Student { ID = 1001, Name = "玲玲", Gender = "Female",
                                         Branch = "CSE", Age = 20 },
            new Student { ID = 1002, Name = "张三", Gender = "Male",
                                         Branch = "ETC", Age = 21  },
            new Student { ID = 1003, Name = "李四", Gender = "Male",
                                         Branch = "CSE", Age = 21  },
            new Student { ID = 1004, Name = "王五", Gender = "Male",
                                         Branch = "CSE", Age = 20  }
        };
        }
    }
}

2.使用Distinct()方法

static void DistinctExp()
        {
            //Using Method Syntax
            var MS = Student.GetAllStudents()
                    .Distinct().ToList();
            //Using Query Syntax
            var QS = (from std in Student.GetAllStudents()
                      select std)
                      .Distinct().ToList();
            foreach (var item in QS)
            {
                Console.WriteLine($"ID : {item.ID} , Name : {item.Name} ");
            }
        }

3.测试结果如下

 

 4.发现问题

为啥这边没有过滤掉重复的列?

原因是:用于比较的默认比较器只检查两个对象引用是否相等,而不检查复杂对象的单个属性值

5.解决问题

1)方案一:实现IEqualityComparer接口

using System.Collections.Generic;

namespace LINQTutorial
{
    public class StudentComparer : IEqualityComparer<Student>
    {
        public bool Equals(Student x, Student y)
        {
            //首先检查两个对象引用是否相等,相等返回true
            if (object.ReferenceEquals(x, y))
            {
                return true;
            }
            //如果任何一个对象的引用为null,返回false
            if (object.ReferenceEquals(x, null) || object.ReferenceEquals(y, null))
            {
                return false;
            }
            //比较每个对象的每一个属性
            return x.ID == y.ID && x.Name == y.Name && x.Gender == y.Gender && x.Branch == y.Branch && x.Age == y.Age;
        }
        public int GetHashCode(Student obj)
        {
            //如果对象为空,
            if (obj == null)
            {
                return 0;
            }

            //获取Hash code值
            int IDHashCode = obj.ID.GetHashCode();
            int NameHashCode = obj.Name == null ? 0 : obj.Name.GetHashCode();
            int GenderHashCode = obj.Gender == null ? 0 : obj.Gender.GetHashCode();
            int BranchHashCode = obj.Branch == null ? 0 : obj.Branch.GetHashCode();
            int AgeHashCode = obj.Age.GetHashCode();
            return IDHashCode ^ NameHashCode ^ GenderHashCode ^ BranchHashCode ^ AgeHashCode;//这么写对么?
        }
    }
}

改变主方法,如下

 static void DistinctSolution1()
        {
            StudentComparer studentComparer = new StudentComparer();
            //Using Method Syntax
            var MS = Student.GetAllStudents()
                    .Distinct(studentComparer).ToList();
            //Using Query Syntax
            var QS = (from std in Student.GetAllStudents()
                      select std)
                      .Distinct(studentComparer).ToList();
            foreach (var item in QS)
            {
                Console.WriteLine($"ID : {item.ID} , Name : {item.Name} ");
            }
            Console.ReadKey();
        }

测试结果如下,符合预期:

 Distinct方法官方参考资料如下:

 

 

 

参考网址:

https://dotnettutorials.net/lesson/linq-distinct-method/

 

标签:Name,Distinct,解决方案,Branch,Linq,Student,Gender,Age,ID
From: https://www.cnblogs.com/keeplearningandsharing/p/16639903.html

相关文章