Drawback of that implementation is the need to specify lambda taking two arguments in order to create a comparer.
Here's a simpler approach.
First of all, usage:
values.Distinct(v => v.Id)
implementation:
public static class EnumerableExtensions
{
public static IEnumerable<T> Distinct<T, TId>(this IEnumerable<T> values, Func<T, TId> projection)
where TId : IEquatable<TId>
{
return values.Distinct(new ProjectingEqualityComparer<T, TId>(projection));
}
class ProjectingEqualityComparer<T, TId> : IEqualityComparer<T>
where TId : IEquatable<TId>
{
readonly Func<T, TId> projection;
public ProjectingEqualityComparer(Func<T, TId> projection)
{
this.projection = projection;
}
public bool Equals(T x, T y)
{
return EqualityComparer<TId>.Default.Equals(projection(x), projection(y));
}
public int GetHashCode(T obj)
{
return EqualityComparer<TId>.Default.GetHashCode(projection(obj));
}
}
}