Click here to Skip to main content
13,632,806 members
Click here to Skip to main content
Add your own
alternative version


2 bookmarked
Posted 13 Apr 2010
Licenced CPOL

LINQ: Enhancing Distinct With The PredicateEqualityComparer

, 15 Apr 2010
Rate this:
Please Sign up or sign in to vote.
LINQ: Enhancing Distinct With The PredicateEqualityComparer

free hit countersToday, I was writing a LINQ query and I needed to select distinct values based on a comparison criteria.

Fortunately, LINQ’s Distinct method allows an equality comparer to be supplied, but, unfortunately, sometimes, this means having to write custom equality comparer.

Because I was going to need more than one equality comparer for this set of tools I was building, I decided to build a generic equality comparer that would just take a custom predicate. Something like this:

public class PredicateEqualityComparer<T> : EqualityComparer<T>
    private Func<T, T, bool> predicate;

    public PredicateEqualityComparer(Func<T, T, bool> predicate)
        : base()
        this.predicate = predicate;

    public override bool Equals(T x, T y)
        if (x != null)
            return ((y != null) && this.predicate(x, y));

        if (y != null)
            return false;

        return true;

    public override int GetHashCode(T obj)
        // Always return the same value to force the call to IEqualityComparer<T>.Equals
        return 0;

Now I can write code like this:

.Distinct(new PredicateEqualityComparer<Item>((x, y) => x.Field == y.Field))

But I felt that I’d lost all conciseness and expressiveness of LINQ and it doesn’t support anonymous types. So I came up with another Distinct extension method:

public static IEnumerable<TSource> Distinct<TSource>
	(this IEnumerable<TSource> source, Func<TSource, TSource, bool> predicate)
    return source.Distinct(new PredicateEqualityComparer<TSource>(predicate));

And the query is now written like this:

.Distinct((x, y) => x.Field == y.Field)

Looks a lot better, doesn’t it? And it works with anonymous types.

Update: I, accidentally, had published the wrong version of the IEqualityComparer<T>.Equals method.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Paulo Morgado
Software Developer (Senior) Paulo Morgado
Portugal Portugal

You may also be interested in...

Comments and Discussions

-- There are no messages in this forum --
Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web04-2016 | 2.8.180712.1 | Last Updated 15 Apr 2010
Article Copyright 2010 by Paulo Morgado
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid