<PackageReference Include="NUnit" Version="3.9.0" />

Lookup<TKey, TElement>

public class Lookup<TKey, TElement> : IEnumerable<IGrouping<TKey, TElement>>, IEnumerable, ILookup<TKey, TElement>
using System.Collections; using System.Collections.Generic; namespace System.Linq { public class Lookup<TKey, TElement> : IEnumerable<IGrouping<TKey, TElement>>, IEnumerable, ILookup<TKey, TElement> { private IGrouping<TKey, TElement> nullGrouping; private Dictionary<TKey, IGrouping<TKey, TElement>> groups; public int Count { get { if (nullGrouping != null) return groups.Count + 1; return groups.Count; } } public IEnumerable<TElement> this[TKey key] { get { if (key == null && nullGrouping != null) return nullGrouping; if (key != null && groups.TryGetValue(key, out IGrouping<TKey, TElement> value)) return value; return new TElement[0]; } } internal Lookup(Dictionary<TKey, List<TElement>> lookup, IEnumerable<TElement> nullKeyElements) { groups = new Dictionary<TKey, IGrouping<TKey, TElement>>(lookup.Comparer); foreach (KeyValuePair<TKey, List<TElement>> item in lookup) { groups.Add(item.Key, new Grouping<TKey, TElement>(item.Key, item.Value)); } if (nullKeyElements != null) nullGrouping = new Grouping<TKey, TElement>(default(TKey), nullKeyElements); } public IEnumerable<TResult> ApplyResultSelector<TResult>(Func<TKey, IEnumerable<TElement>, TResult> resultSelector) { if (this.nullGrouping != null) yield return resultSelector(this.nullGrouping.Key, this.nullGrouping); Dictionary<TKey, IGrouping<TKey, TElement>>.ValueCollection.Enumerator enumerator = this.groups.Values.GetEnumerator(); try { while (enumerator.MoveNext()) { IGrouping<TKey, TElement> current = enumerator.Current; yield return resultSelector(current.Key, current); } } finally { ((IDisposable)enumerator).Dispose(); } enumerator = default(Dictionary<TKey, IGrouping<TKey, TElement>>.ValueCollection.Enumerator); } public bool Contains(TKey key) { if (key == null) return nullGrouping != null; return groups.ContainsKey(key); } public IEnumerator<IGrouping<TKey, TElement>> GetEnumerator() { if (this.nullGrouping != null) yield return this.nullGrouping; Dictionary<TKey, IGrouping<TKey, TElement>>.ValueCollection.Enumerator enumerator = this.groups.Values.GetEnumerator(); try { while (enumerator.MoveNext()) { IGrouping<TKey, TElement> current = enumerator.Current; yield return current; } } finally { ((IDisposable)enumerator).Dispose(); } enumerator = default(Dictionary<TKey, IGrouping<TKey, TElement>>.ValueCollection.Enumerator); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } }