C# : Avoid loops, start using equality comparer
Tags: csharp, dotnet, coding, dotnetcore
Published: 2024-05-22 17:07:23

Are you writing multiple loops to compare two lists of same type in C# because of complex comparison criteria ? 

There is an another simple way to achieve it. 

Use Equality Comparer and write your own comparison logic with complex objects.

Remember the 'GetHashCode' logic has to return same value for duplicate instances. 

Simple Example:
EmployeeEqualityComparer implements IEqualityComparer<Employee> which defines criteria on how to compare two lists of same type through methods 'Equals' & 'GetHashCode'.

```c#

public class EmployeeEqualityComparer : IEqualityComparer<Employee>
{
    public bool Equals(Employee? x, Employee? y)
    {
        if(x is null || y is null) return false;

        if(ReferenceEquals(x,y))return true;

        return x.Id == y.Id && x.DepartmentId == y.DepartmentId;
    }

    public int GetHashCode([DisallowNull] Employee obj)
    {
        return obj.Id + obj.DepartmentId;
    }
}
```

Employee model class:
```c#
public class Employee
{
    public string Name{get;set;}
    public int Id {get;set;}
    public string Department{get;set;}
    public int DepartmentId{get;set;}
    public string City{get;set;}
    public string Zip{get;set;}
}
```

EmployeeEqualityComparerTestClass to compare two lists of same type and test equality comparer:
```c#
    public class EmployeeEqualityComparerTestClass
    {
        public void EqualityCheck()
        {
            //prepare test data

            var employeesA = new List<Employee>()
            {
                 new Employee()
                    {
                        Name = "Nirmal kumar",
                        Id = 1,
                        Department = "Engineering",
                        DepartmentId = 1,
                        City = "Raleigh",
                        Zip = "27616"
                    },
                     new Employee()
                    {
                        Name = "John",
                        Id = 2,
                        Department = "Engineering",
                        DepartmentId = 1,
                        City = "Raleigh",
                        Zip = "27616"
                    },
                    new Employee()
                    {
                        Name = "Nirmal kumar",
                        Id = 1,
                        Department = "Engineering",
                        DepartmentId = 1,
                        City = "Raleigh",
                        Zip = "27616"
                    },
            };

            var employeesB = new List<Employee>()
            {
                 new Employee()
                    {
                        Name = "Nirmal kumar",
                        Id = 1,
                        Department = "Engineering",
                        DepartmentId = 1,
                        City = "Raleigh",
                        Zip = "27616"
                    },
                     new Employee()
                    {
                        Name = "Tesla",
                        Id = 3,
                        Department = "Engineering",
                        DepartmentId = 1,
                        City = "Raleigh",
                        Zip = "27616"
                    }
            };

            //prepare equality comparer
            var equalityComparer = new EmployeeEqualityComparer();

            //check distinct using equality comparer
            var distinctEmployees = employeesA.Distinct(equalityComparer);

            Console.WriteLine($"Total distinct employees : {distinctEmployees.Count()}");
            Console.WriteLine("Distinct employee names in employeeA list:");
            foreach(var employee in distinctEmployees)
            {
                Console.WriteLine(employee.Name);
            }

            Console.WriteLine();
            Console.WriteLine("Let's union two different lists of same type with duplicates");

            //compare two lists of same type using equality comparer
            var employees = employeesA.Union(employeesB, equalityComparer);

            Console.WriteLine($"Total distinct employees from 2 lists : {employees.Count()}");
            Console.WriteLine("Distinct employee names:");
            foreach(var employee in employees)
            {
                Console.WriteLine(employee.Name);
            }

            Console.ReadKey();
        }
    }
```

Output:
Total distinct employees : 2
Distinct employee names in employeeA list:
Nirmal kumar
John

Let's union two different lists of same type with duplicates
Total distinct employees from 2 lists : 3
Distinct employee names:
Nirmal kumar
John
Tesla