c# - 我们可以使用 LINQ 扩展方法 SequenceEqual 使用 IEqualityComparer 接口(interface)逐字段比较两个复杂集合吗

标签 c# linq iequalitycomparer

我正在尝试使用 IEqualityComparer 逐字段比较 2 个集合中的 2 个字段。 IEqualityComparer 仅比较 1 个字段“名称”。我也想比较“标记”。

在 Java 中,我们有 comparator 接口(interface)来比较 Equals 方法中的多个字段。

using System;
using System.Linq;
using System.Collections.Generic;

    public class Program
    {
        public static void Main()
        {
            IList<Student> studentList1 = new List<Student>()
            {
                new Student(){ name="aaaaa", mark = 95, },
                new Student(){ name="bbbb", mark = 25, },
                new Student(){ name="ccc",  mark = 80 }
            };

            IList<Student> studentList2 = new List<Student>()
            {
                new Student(){ name="aaaaa", mark = 95, },
                new Student(){ name="bbbb", mark = 5, },
                new Student(){ name="ccc",  mark = 80 }
            };

            bool isEqual = studentList1.SequenceEqual(studentList2, new StudentComparer());
            Console.WriteLine("Names in 2 collections are {0}", isEqual?"equal":"not equal");   
        }
    }

    public class Student
    {
        public string name { get; set; }
        public int mark { get; set; }
    }

    public class StudentComparer : IEqualityComparer<Student>
    {
        public bool Equals(Student x, Student y)
        {
            if (x.name == y.name)
                return true;
            return false;
        }

        public int GetHashCode(Student obj)
        {
            return obj.GetHashCode();
        }
    }

实际结果: 2 个集合中的名称相等 预期结果: 2 个集合中的名称相等 2 个集合中的标记不相等

最佳答案

这里的问题是 Object.GetHashCode() 在对象之间必须是唯一的。这意味着当 SequenceEqual(...) 调用 comparer.GetHashCode(...) 时,它会为不同的对象实例获取不同的值,尽管您已经声明它们相等在 StudentComparer.Equals(...) 中。

所有这些意味着,您应该返回仅在 Student 实例根据 IEqualityComparer 是唯一的情况下唯一的哈希码。例如,您可以将 StudentComparer.GetHashCode(Student obj) 的实现更改为: 返回 obj.name.GetHashCode()

关于c# - 我们可以使用 LINQ 扩展方法 SequenceEqual 使用 IEqualityComparer 接口(interface)逐字段比较两个复杂集合吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56268957/

相关文章:

c# - EF Core,通过从字符串进行 int 转换在 SQL 服务器上执行

c# - 如何重定向到另一个网址

javascript - JavaScript 是否具有与 LINQ 的 Select 语句类似的功能?

c# - 多个引用类型字段上的 LINQ GroupBy;自定义相等比较器

c# - 附加类型的实体失败,因为相同类型的另一个实体已经具有相同的主键值

C#:在将 DataTable 绑定(bind)到 GridView 时更改列的顺序

c# - 左连接,右为空

c# - 使用 Linq 如何从两个表中获取用户列表及其上次登录

c# - 我应该如何实现 IEqualityComparer<T>.Equals

c# - HashSet<T>.CreateSetComparer() 无法指定 IEqualityComparer<T>,是否有替代方案?