//****************************************************************************************************** // 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 { /// /// A faster and functionally equivalent implementation of /// /// The type of the element in the collection /// /// /// is based upon an . 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 and shadows many of the methods to call /// instead of . /// /// /// Since this class references the same underlying object, it can be /// successfully implemented as a or casted it its underlying type /// . /// /// /// Profiling this class yield a ForEach loop and For loop that executes between /// 2-4 times faster than . 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). /// /// /// This performance is negated if accessing this class via the IList interface. When possible, use /// only strongly typed names. /// /// // Note that explicit re-declaration of interfaces is required here because of shadowed methods public class ListCollection : Collection, IList, IList, IReadOnlyList { #region [ Members ] // Fields private readonly List m_list; // Strongly typed reference to Items collection #endregion #region [ Constructors ] /// /// Creates a /// /// a list to wrap this class around. public ListCollection(List list) : base(list) { m_list = (List)base.Items; } /// /// Creates a /// public ListCollection() : this(new List()) { } #endregion #region [ Properties ] /// /// Gets the number of elements contained in the . /// /// /// The number of elements contained in the . /// public new int Count { get { return m_list.Count; } } /// /// Gets or sets the element at the specified index. /// /// /// The element at the specified index. /// /// The zero-based index of the element to get or set. /// is not a valid index in the . /// The property is set and the is read-only. public new T this[int index] { get { return m_list[index]; } set { if (index < 0 || index >= m_list.Count) ThrowOutOfRangeException(); SetItem(index, value); } } /// /// Gets a wrapper around the . /// /// /// A wrapper around the . /// protected new List Items { get { return m_list; } } #endregion #region [ Methods ] /// /// Adds an item to the . /// /// The object to add to the . /// The is read-only. public new void Add(T item) { InsertItem(m_list.Count, item); } /// /// Removes all items from the . /// /// The is read-only. public new void Clear() { ClearItems(); } /// /// Removes all elements from the . /// protected override void ClearItems() { m_list.Clear(); } /// /// Determines whether the contains a specific value. /// /// /// true if is found in the ; otherwise, false. /// /// The object to locate in the . public new bool Contains(T item) { return m_list.Contains(item); } /// /// Copies the elements of the to an , starting at a particular index. /// /// /// The one-dimensional that is the destination of the elements copied from . /// The must have zero-based indexing.The zero-based index in at which copying begins. /// /// is null. /// is less than 0. /// The number of elements in the source is greater than the available space from to the end of the destination . public new void CopyTo(T[] array, int index) { m_list.CopyTo(array, index); } /// /// Returns an enumerator that iterates through the . /// /// /// An for the . /// public new List.Enumerator GetEnumerator() { return m_list.GetEnumerator(); } /// /// Determines the index of a specific item in the . /// /// /// The index of if found in the list; otherwise, -1. /// /// The object to locate in the . public new int IndexOf(T item) { return m_list.IndexOf(item); } /// /// Inserts an item to the at the specified index. /// /// The zero-based index at which should be inserted. /// The object to insert into the . /// is not a valid index in the . /// The is read-only. public new void Insert(int index, T item) { if (index < 0 || index > m_list.Count) ThrowOutOfRangeException(); InsertItem(index, item); } /// /// Inserts an element into the at the specified index. /// /// The zero-based index at which should be inserted. /// The object to insert. The value can be null for reference types. /// is less than zero.-or- is greater than . protected override void InsertItem(int index, T item) { m_list.Insert(index, item); } /// /// Removes the first occurrence of a specific object from the . /// /// /// true if was successfully removed from the ; otherwise, false. This method also returns false if is not found in the original . /// /// The object to remove from the . /// The is read-only. public new bool Remove(T item) { int index = m_list.IndexOf(item); if (index < 0) return false; RemoveItem(index); return true; } /// /// Removes the element at the specified index of the . /// /// The zero-based index of the element to remove. /// is less than zero.-or- is equal to or greater than . public new void RemoveAt(int index) { if (index < 0 || index >= m_list.Count) ThrowOutOfRangeException(); RemoveItem(index); } /// /// Removes the element at the specified index of the . /// /// The zero-based index of the element to remove. /// is less than zero.-or- is equal to or greater than . protected override void RemoveItem(int index) { m_list.RemoveAt(index); } /// /// Replaces the element at the specified index. /// /// The zero-based index of the element to replace. /// The new value for the element at the specified index. The value can be null for reference types. /// is less than zero.-or- is greater than . 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 } }