I've had to search for this quite a few times so I figured it was probably time to write it up. I actually did find this answer somewhere else (here, if you're interested) and modified it only slightly to follow my standards.
As I often (somehow) forget, the default .Distinct() extension in System.Linq for an IEnumerable just checks to see if objects are the exact same as each other. You may recall in C# that being the exact same means the two objects are actually references to the same exact object. I can say with a good amount of confidence that in 16+ years of working in C# that's never actually been what I'm trying to do when I use .Distinct(). I'd say my most common usage is determining whether two objects have the same data on them - usually one specific field (like an ID field, for example). There are Stack Overflow posts and extension libraries out there that include this, but I'm pretty loathe to bring in a whole library for one simple extension method. Which brings us to today.
I'm using Dapper to get a list of objects from the database and then using the splitOn feature to get the children of those objects. Think of a teacher and students: I'm getting all the teachers in the school and then all of each teacher's students in a single query, then I want to break the students out according to their teachers by using the splitOn feature of Dapper. That's no problem and doesn't even require me to use .Distinct(). If I also include the clubs that each teacher oversees, I could easily end up with duplicate students in my results. The easiest way to get the distinct students in my results would be to use the .Distinct() extension method included in System.Linq, if only that worked the way it seems like it should. Instead, I'll have to write my own. So here we are.
1: public static IEnumerable<T> DistinctBy<T>(this IEnumerable<T> list, Func<T, object> propertySelector) where T : class
2: {
3: return list.GroupBy(propertySelector).Select(x => x.First());
4: }
That's it, really. The somewhat obvious flaw is that we'll take the first match we find, but if you're looking for distinct objects, that really shouldn't be too big of a deal. Hopefully this helps you (even if "you" are really just future me).