313 lines · 12.9 KB · C#
RawDownload
//******************************************************************************************************//  ListCollection.cs - Gbtc////  Copyright © 2014, Grid Protection Alliance.  All Rights Reserved.////  Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See//  the NOTICE file distributed with this work for additional information regarding copyright ownership.//  The GPA licenses this file to you under the MIT License (MIT), the "License"; you may//  not use this file except in compliance with the License. You may obtain a copy of the License at:////      http://www.opensource.org/licenses/MIT////  Unless agreed to in writing, the subject software distributed under the License is distributed on an//  "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the//  License for the specific language governing permissions and limitations.////  Code Modification History://  ----------------------------------------------------------------------------------------------------//  05/09/2014 - Steven E. Chisholm//       Generated original version of source code.////****************************************************************************************************** using System;using System.Collections;using System.Collections.Generic;using System.Collections.ObjectModel; namespace GSF.Collections{    /// <summary>    /// A faster and functionally equivalent implementation of <see cref="Collection{T}"/>     /// </summary>    /// <typeparam name="T">The type of the element in the collection</typeparam>    /// <remarks>    /// <para>    /// <see cref="Collection{T}"/> is based upon an <see cref="IList{T}"/>. This means any simple call    /// to the class is a function call that cannot be in-lined. This implementation forces the underlying    /// item to be <see cref="List{T}"/> and shadows many of the methods to call <see cref="List{T}"/>     /// instead of <see cref="IList{T}"/>.     /// </para>    /// <para>    /// Since this class references the same underlying <see cref="List{T}"/> object, it can be     /// successfully implemented as a <see cref="ListCollection{T}"/> or casted it its underlying type    /// <see cref="Collection{T}"/>.    /// </para>    /// <para>    /// Profiling this class yield a ForEach loop and For loop that executes between     /// 2-4 times faster than <see cref="Collection{T}"/>. This depends on the number of items in the    /// list. The fewer the faster. Other operations such as Add/Insert/Remove are closer to 50% faster.    /// Count is now in-lined (~20 times faster).    /// </para>    /// <para>    /// This performance is negated if accessing this class via the IList interface. When possible, use    /// only strongly typed names.    /// </para>    /// </remarks>    // Note that explicit re-declaration of interfaces is required here because of shadowed methods    public class ListCollection<T> : Collection<T>, IList<T>, IList, IReadOnlyList<T>    {        #region [ Members ]         // Fields        private readonly List<T> m_list;    // Strongly typed reference to Items collection         #endregion         #region [ Constructors ]         /// <summary>        /// Creates a <see cref="ListCollection{T}"/>        /// </summary>        /// <param name="list">a list to wrap this class around.</param>        public ListCollection(List<T> list)            : base(list)        {            m_list = (List<T>)base.Items;        }         /// <summary>        /// Creates a <see cref="ListCollection{T}"/>        /// </summary>        public ListCollection()            : this(new List<T>())        {        }         #endregion         #region [ Properties ]         /// <summary>        /// Gets the number of elements contained in the <see cref="ICollection{T}"/>.        /// </summary>        /// <returns>        /// The number of elements contained in the <see cref="ICollection{T}"/>.        /// </returns>        public new int Count        {            get            {                return m_list.Count;            }        }         /// <summary>        /// Gets or sets the element at the specified index.        /// </summary>        /// <returns>        /// The element at the specified index.        /// </returns>        /// <param name="index">The zero-based index of the element to get or set.</param>        /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> is not a valid index in the <see cref="IList{T}"/>.</exception>        /// <exception cref="NotSupportedException">The property is set and the <see cref="IList{T}"/> is read-only.</exception>        public new T this[int index]        {            get            {                return m_list[index];            }            set            {                if (index < 0 || index >= m_list.Count)                    ThrowOutOfRangeException();                 SetItem(index, value);            }        }         /// <summary>        /// Gets a <see cref="IList{T}"/> wrapper around the <see cref="Collection{T}"/>.        /// </summary>        /// <returns>        /// A <see cref="IList{T}"/> wrapper around the <see cref="Collection{T}"/>.        /// </returns>        protected new List<T> Items        {            get            {                return m_list;            }        }         #endregion         #region [ Methods ]         /// <summary>        /// Adds an item to the <see cref="ICollection{T}"/>.        /// </summary>        /// <param name="item">The object to add to the <see cref="ICollection{T}"/>.</param>        /// <exception cref="NotSupportedException">The <see cref="ICollection{T}"/> is read-only.</exception>        public new void Add(T item)        {            InsertItem(m_list.Count, item);        }         /// <summary>        /// Removes all items from the <see cref="ICollection{T}"/>.        /// </summary>        /// <exception cref="NotSupportedException">The <see cref="ICollection{T}"/> is read-only. </exception>        public new void Clear()        {            ClearItems();        }         /// <summary>        /// Removes all elements from the <see cref="Collection{T}"/>.        /// </summary>        protected override void ClearItems()        {            m_list.Clear();        }         /// <summary>        /// Determines whether the <see cref="ICollection{T}"/> contains a specific value.        /// </summary>        /// <returns>        /// true if <paramref name="item"/> is found in the <see cref="ICollection{T}"/>; otherwise, false.        /// </returns>        /// <param name="item">The object to locate in the <see cref="ICollection{T}"/>.</param>        public new bool Contains(T item)        {            return m_list.Contains(item);        }         /// <summary>        /// Copies the elements of the <see cref="ICollection{T}"/> to an <see cref="Array"/>, starting at a particular <see cref="Array"/> index.        /// </summary>        /// <param name="array">        /// The one-dimensional <see cref="Array"/> that is the destination of the elements copied from <see cref="ICollection{T}"/>.         /// The <see cref="Array"/> must have zero-based indexing.</param><param name="index">The zero-based index in <paramref name="array"/> at which copying begins.        /// </param>        /// <exception cref="ArgumentNullException"><paramref name="array"/> is null.</exception>        /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> is less than 0.</exception>        /// <exception cref="ArgumentException">The number of elements in the source <see cref="ICollection{T}"/> is greater than the available space from <paramref name="index"/> to the end of the destination <paramref name="array"/>.</exception>        public new void CopyTo(T[] array, int index)        {            m_list.CopyTo(array, index);        }         /// <summary>        /// Returns an enumerator that iterates through the <see cref="Collection{T}"/>.        /// </summary>        /// <returns>        /// An <see cref="IEnumerator{T}"/> for the <see cref="Collection{T}"/>.        /// </returns>        public new List<T>.Enumerator GetEnumerator()        {            return m_list.GetEnumerator();        }         /// <summary>        /// Determines the index of a specific item in the <see cref="IList{T}"/>.        /// </summary>        /// <returns>        /// The index of <paramref name="item"/> if found in the list; otherwise, -1.        /// </returns>        /// <param name="item">The object to locate in the <see cref="IList{T}"/>.</param>        public new int IndexOf(T item)        {            return m_list.IndexOf(item);        }         /// <summary>        /// Inserts an item to the <see cref="IList{T}"/> at the specified index.        /// </summary>        /// <param name="index">The zero-based index at which <paramref name="item"/> should be inserted.</param>        /// <param name="item">The object to insert into the <see cref="IList{T}"/>.</param>        /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> is not a valid index in the <see cref="IList{T}"/>.</exception>        /// <exception cref="NotSupportedException">The <see cref="IList{T}"/> is read-only.</exception>        public new void Insert(int index, T item)        {            if (index < 0 || index > m_list.Count)                ThrowOutOfRangeException();             InsertItem(index, item);        }         /// <summary>        /// Inserts an element into the <see cref="Collection{T}"/> at the specified index.        /// </summary>        /// <param name="index">The zero-based index at which <paramref name="item"/> should be inserted.</param>        /// <param name="item">The object to insert. The value can be null for reference types.</param>        /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> is less than zero.-or-<paramref name="index"/> is greater than <see cref="Collection{T}.Count"/>.</exception>        protected override void InsertItem(int index, T item)        {            m_list.Insert(index, item);        }         /// <summary>        /// Removes the first occurrence of a specific object from the <see cref="ICollection{T}"/>.        /// </summary>        /// <returns>        /// true if <paramref name="item"/> was successfully removed from the <see cref="ICollection{T}"/>; otherwise, false. This method also returns false if <paramref name="item"/> is not found in the original <see cref="ICollection{T}"/>.        /// </returns>        /// <param name="item">The object to remove from the <see cref="ICollection{T}"/>.</param>        /// <exception cref="NotSupportedException">The <see cref="ICollection{T}"/> is read-only.</exception>        public new bool Remove(T item)        {            int index = m_list.IndexOf(item);             if (index < 0)                return false;             RemoveItem(index);             return true;        }         /// <summary>        /// Removes the element at the specified index of the <see cref="Collection{T}"/>.        /// </summary>        /// <param name="index">The zero-based index of the element to remove.</param>        /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> is less than zero.-or-<paramref name="index"/> is equal to or greater than <see cref="Collection{T}.Count"/>.</exception>        public new void RemoveAt(int index)        {            if (index < 0 || index >= m_list.Count)                ThrowOutOfRangeException();             RemoveItem(index);        }         /// <summary>        /// Removes the element at the specified index of the <see cref="Collection{T}"/>.        /// </summary>        /// <param name="index">The zero-based index of the element to remove.</param>        /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> is less than zero.-or-<paramref name="index"/> is equal to or greater than <see cref="Collection{T}.Count"/>.</exception>        protected override void RemoveItem(int index)        {            m_list.RemoveAt(index);        }         /// <summary>        /// Replaces the element at the specified index.        /// </summary>        /// <param name="index">The zero-based index of the element to replace.</param>        /// <param name="item">The new value for the element at the specified index. The value can be null for reference types.</param>        /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> is less than zero.-or-<paramref name="index"/> is greater than <see cref="Collection{T}.Count"/>.</exception>        protected override void SetItem(int index, T item)        {            m_list[index] = item;        }         private static void ThrowOutOfRangeException()        {            // ReSharper disable once NotResolvedInText            throw new ArgumentOutOfRangeException("index");        }         #endregion    }}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t