Implement IEquatable to Power Up LINQ Distinct Queries

By Peter Bromberg

The LINQ Distinct operator is not that smart, but you can help it by implementing IEquatable on your objects. Here's how.

In order for the LINQ Distinct operator to function correctly in a multi-field comparison, we must provide it with a custom implementation that allows it to truly return what we define as "distinct". Otherwise, it may fail to work.

In order to implement IEquatable in a class, we need only the Equals and to override the GetHashCode methods. Equals in the example compares both the first and last names and returns true for a match and false otherwise. GetHashCode similarly returns a unique hash value based on the fact that both the first and last name properties of the class are what make an instance "distinct".

Here is a sample Author class that properly implements IEquatable:

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

namespace QuotationLib
{
public class Author : IEquatable<Author>
{

public string FirstName { get; set; }
public string LastName { get; set; }
public string AuthorInfo { get; set; }

public bool Equals(Author other)
{
if (FirstName == other.FirstName && LastName == other.LastName) return true;
return false;
}

public override int GetHashCode()
{
int hashFirstName = FirstName == null ? 0 : FirstName.GetHashCode();
int hashLastName = LastName == null ? 0 : LastName.GetHashCode();
return hashFirstName ^ hashLastName;
}
}
}

With the Equals and the GetHashCode methods in place, we can now issue a query like this:

public static List<Author> GetAuthors()
{
var Authors = (
from q in Quotes
select
new Author()
{
AuthorInfo = q.AuthorInfo,
FirstName = q.AuthorFirstName,
LastName = q.AuthorLastName
}).Distinct().ToList();
return Authors;
}

The above will now return a true "distinct" list of our authors.Without this, Distinct wouldn't know what to do and you would still get all Authors in the collection.


Implement IEquatable to Power Up LINQ Distinct Queries  (1456 Views)