Use a delegate for the equality comparer for LINQ’s Distinct()

Distinct takes an IEqualityComparer as the second argument, so you will need an IEqualityComparer. It’s not too hard to make a generic one that will take a delegate, though. Of course, this has probably already been implemented in some places, such as MoreLINQ suggested in one of the other answers.

You could implement it something like this:

public static class Compare
{
    public static IEnumerable<T> DistinctBy<T, TIdentity>(this IEnumerable<T> source, Func<T, TIdentity> identitySelector)
    {
        return source.Distinct(Compare.By(identitySelector));
    }

    public static IEqualityComparer<TSource> By<TSource, TIdentity>(Func<TSource, TIdentity> identitySelector)
    {
        return new DelegateComparer<TSource, TIdentity>(identitySelector);
    }

    private class DelegateComparer<T, TIdentity> : IEqualityComparer<T>
    {
        private readonly Func<T, TIdentity> identitySelector;

        public DelegateComparer(Func<T, TIdentity> identitySelector)
        {
            this.identitySelector = identitySelector;
        }

        public bool Equals(T x, T y)
        {
            return Equals(identitySelector(x), identitySelector(y));
        }

        public int GetHashCode(T obj)
        {
            return identitySelector(obj).GetHashCode();
        }
    }
}

Which gives you the syntax:

source.DistinctBy(a => a.Id);

Or, if you feel it’s clearer this way:

source.Distinct(Compare.By(a => a.Id));

Leave a Comment

404 Not Found

Not Found

The requested URL was not found on this server.

Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.