public static IEnumerable <TGroup> GroupByGeneric <T, TKey, TValue, TGroupState, TGroup>( this IEnumerable <KeyValuePair <TKey, TValue> > source, ICollector <KeyValuePair <TKey, TValue>, TGroupState, TGroup> collector ) { var groups = new Dictionary <TKey, TGroupState>(); foreach (var item in source) { if (!groups.TryGetValue(item.Key, out var group)) { groups[item.Key] = collector.Add(group, item); } else { groups.Add(item.Key, collector.Create(item)); } } foreach (var kv in groups) { yield return(collector.Complete(kv.Value)); } }