Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can we compare two complex collections field by field using IEqualityComparer interface using LINQ extension method SequenceEqual

I'm trying to use IEqualityComparer to compare 2 fields from 2 collections field by field. IEqualityComparer is comparing only 1 field "name". I want to compare "mark" as well.

In Java, we have comparator interface to compare more than one fields in Equals method.

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();
        }
    }

Actual Result: Names in 2 collections are equal Expected Result: Names in 2 collections are equal Marks in 2 collections are not equal

like image 243
HEMAMBUJAVALLY VIRAPPANE Avatar asked Oct 22 '25 04:10

HEMAMBUJAVALLY VIRAPPANE


1 Answers

Your issue here is that Object.GetHashCode() is necessarily unique between objects. This means that when SequenceEqual(…) calls comparer.GetHashCode(…), it will get different values for different instances of objects, despite the fact that you have declared them equal in StudentComparer.Equals(…).

What all of this means is that, you should return hash codes which are unique in only the situations where instances of Student are unique according to the IEqualityComparer. For example, you could change your implementation of StudentComparer.GetHashCode(Student obj) to: return obj.name.GetHashCode()

like image 87
corranrogue9 Avatar answered Oct 23 '25 19:10

corranrogue9