using System.Collections.Generic;
using System.Runtime.InteropServices;
public static class Program
public static void Main()
List<int> list = new() {4, 5, 7, 3, 5, 4, 2, 4};
Console.WriteLine($"Before: [{String.Join(", ", list)}]");
int removedCount = list.RemoveDuplicatesByKey(x => x);
Console.WriteLine($"After: [{String.Join(", ", list)}], Removed: {removedCount}");
public static int RemoveDuplicatesByKey<TSource, TKey>(this List<TSource> list,
Func<TSource, TKey> keySelector,
IEqualityComparer<TKey> comparer = default)
ArgumentNullException.ThrowIfNull(list);
ArgumentNullException.ThrowIfNull(keySelector);
Dictionary<TKey, int> occurences = new(list.Count, comparer);
foreach (TSource item in list)
CollectionsMarshal.GetValueRefOrAddDefault(
occurences, keySelector(item), out _)++;
return list.RemoveAll(item => occurences.TryGetValue(
keySelector(item), out int value) && value > 1);