Back to results for “LINQ”
C# › LINQ

How would you write a custom LINQ extension method that integrates seamlessly with the standard method-chaining style, like a 'DistinctBy' before it existed natively?

Advanced

Answer

Write a generic extension method on IEnumerable<T> that internally uses a HashSet (often of the KEY, not the whole object) to track already-seen items, yielding only the FIRST occurrence for each unique key — implemented lazily with yield return so it composes correctly with the rest of a deferred LINQ chain.
public static IEnumerable<T> MyDistinctBy<T, TKey>(this IEnumerable<T> source, Func<T, TKey> keySelector) {
  var seenKeys = new HashSet<TKey>();
  foreach (var item in source) {
    if (seenKeys.Add(keySelector(item))) yield return item; // Add() returns false if already present
  }
}
var uniqueByEmail = users.MyDistinctBy(u => u.Email).ToList();
Real-world example Deduplicating a list of orders by customer ID, keeping only the first order per customer, before .NET 6 added native DistinctBy().

Common follow-ups: Why is it important that this custom extension method ALSO be implemented lazily (yield return), rather than eagerly building a List<T>?