// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. using System.Collections; using System.Collections.Generic; namespace System.Linq.Internal { /// Adapted from System.Linq.Grouping from .NET Framework /// Source: https://github.com/dotnet/corefx/blob/b90532bc97b07234a7d18073819d019645285f1c/src/System.Linq/src/System/Linq/Grouping.cs#L64 internal class Grouping : IGrouping, IList { internal TKey _key; internal int _hashCode; internal TElement[] _elements; internal int _count; internal Grouping _hashNext; internal Grouping _next; internal Grouping() { } internal void Add(TElement element) { if (_elements.Length == _count) { Array.Resize(ref _elements, checked(_count * 2)); } _elements[_count] = element; _count++; } internal void Trim() { if (_elements.Length != _count) { Array.Resize(ref _elements, _count); } } public IEnumerator GetEnumerator() { for (int i = 0; i < _count; i++) { yield return _elements[i]; } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } // DDB195907: implement IGrouping<>.Key implicitly // so that WPF binding works on this property. public TKey Key { get { return _key; } } int ICollection.Count { get { return _count; } } bool ICollection.IsReadOnly { get { return true; } } void ICollection.Add(TElement item) { throw new NotSupportedException(Strings.NOT_SUPPORTED); } void ICollection.Clear() { throw new NotSupportedException(Strings.NOT_SUPPORTED); } bool ICollection.Contains(TElement item) { return Array.IndexOf(_elements, item, 0, _count) >= 0; } void ICollection.CopyTo(TElement[] array, int arrayIndex) { Array.Copy(_elements, 0, array, arrayIndex, _count); } bool ICollection.Remove(TElement item) { throw new NotSupportedException(Strings.NOT_SUPPORTED); } int IList.IndexOf(TElement item) { return Array.IndexOf(_elements, item, 0, _count); } void IList.Insert(int index, TElement item) { throw new NotSupportedException(Strings.NOT_SUPPORTED); } void IList.RemoveAt(int index) { throw new NotSupportedException(Strings.NOT_SUPPORTED); } TElement IList.this[int index] { get { if (index < 0 || index >= _count) { throw new ArgumentOutOfRangeException(nameof(index)); } return _elements[index]; } set { throw new NotSupportedException(Strings.NOT_SUPPORTED); } } } }