#if NET20 || NET30 || !NET_4_6 using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using LinqInternal.Collections.Specialized; using LinqInternal.Collections.ThreadSafe; using LinqInternal.Core; namespace System.Linq.Reimplement { public class Lookup : ILookup { private readonly IDictionary _groupings; internal Lookup(IEqualityComparer comparer) { if (typeof(TKey).CanBeNull()) { _groupings = new NullAwareDictionary(comparer); } else { _groupings = new Dictionary(comparer); } } public int Count { get { return _groupings.Count; } } public IEnumerable this[TKey key] { get { Grouping grouping; if (_groupings.TryGetValue(key, out grouping)) { return grouping; } else { return ArrayReservoir.EmptyArray; } } } public IEnumerable ApplyResultSelector(Func, TResult> resultSelector) { // MICROSFT doens't do a null check for resultSelector foreach (var group in _groupings.Values) { yield return resultSelector(group.Key, group); } } public bool Contains(TKey key) { return _groupings.ContainsKey(key); } public IEnumerator> GetEnumerator() { foreach (var grouping in _groupings.Values) { yield return grouping; } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } internal static Lookup Create(IEnumerable source, Func keySelector, Func elementSelector, IEqualityComparer comparer) { if (source == null) { throw new ArgumentNullException("source"); } if (elementSelector == null) { throw new ArgumentNullException("elementSelector"); } if (keySelector == null) { throw new ArgumentNullException("keySelector"); } var result = new Lookup(comparer); foreach (var item in source) { result.GetOrCreateGrouping(keySelector(item)).Add(elementSelector(item)); } return result; } private ICollection GetOrCreateGrouping(TKey key) { Grouping grouping; if (!_groupings.TryGetValue(key, out grouping)) { grouping = new Grouping(key); _groupings.Add(key, grouping); } return grouping.Items; } internal sealed class Grouping : IGrouping { private readonly Collection _items; internal Grouping(TKey key) { _items = new Collection(); Key = key; } public Collection Items { get { return _items; } } public TKey Key { get; set; } public IEnumerator GetEnumerator() { return _items.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return _items.GetEnumerator(); } } } } #endif